Skip to content

Instantly share code, notes, and snippets.

@MGF15
Created August 4, 2023 15:05
Show Gist options
  • Save MGF15/843f19334095300bcb5a08db9bfb8227 to your computer and use it in GitHub Desktop.
Save MGF15/843f19334095300bcb5a08db9bfb8227 to your computer and use it in GitHub Desktop.
Arbitrum Bot Race Report
ID Title Category Severity Instances
[1] Centralization Risk for trusted owners Centralization / Privilege Med 7
[2] will not work properly on Optimism due to use of block.number Volatile Code Med 4
[3] Initializers could be front-run Data Flow Low 3
[4] Loss of precision Data Flow Low 1
[5] Use safeTransferOwnership instead of transferOwnership function Control Flow Low 2
[6] Unbounded loop Control Flow Low 21
[7] Use Ownable2Step's transfer function rather than Ownable's for transfers of ownership Centralization / Privilege Low 1
[8] Functions return bool true but cannot return false Logical Issue Low 6
[9] Divide by Zero Logical Issue Low 1
[10] off-by-one timestamp error Logical Issue Low 1
[11] TransferOwnership Should Be Two Step Logical Issue Low 2
[12] Hardcode the address causes no future updates Volatile Code Low 2
[13] abi.encodePacked() should not be used with dynamic types when passing the result to a hash function such as keccak256() Control Flow Low 1
[14] MISSING ZERO ADDRESS VALIDATION Volatile Code Low 1
[15] For loops in public or external functions should be avoided due to high gas costs and possible DOS Control Flow Low 8
[16] Lack of Storage Gap Control Flow Low 2
[17] Unprotected Initializer Controal Flow low 3
[18] Functions guaranteed to revert when called by normal users can be marked payable Gas Optimization Informational 5
[19] Imports could be organized more systematically Coding Style Informational 71
[20] Use a more recent version of solidity Coding Style Informational 18
[21] Consider using delete rather than assigning zero to clear values Gas Optimization Informational 1
[22] Use of bytes.concat() instead of abi.encodePacked() Gas Optimization Informational 1
[23] Variables need not be initialized to zero Coding Style Informational 23
[24] Use a single file for all system-wide constants Coding Style Informational 11
[25] Not using the named return variables anywhere in the function is confusing Coding Style Informational 16
[26] Unsigned divisions can be marked as unchecked Control Flow Informational 1
[27] Non-external/public function names should begin with an underscore Coding Style Informational 2
[28] Uppercase immutable variables Coding Style Informational 21
[29] block.timestamp used as time proxy Volatile Code Informational 4
[30] Interfaces should be indicated with an I prefix in the contract name. Coding Style Informational 1
[31] Consider using named mappings Coding Style Informational 3
[32] Consider disabling renounceOwnership() Control Flow Informational 1
[33] addresss shouldn't be hard-coded Logical Issue Informational 2
[34] Interfaces should be defined in separate files from their usage Coding Style Informational 1
[35] Use replace and pop instead of the delete keyword to removing an item from an array Control Flow Informational 1
[36] Consider bounding input array length Control Flow Informational 21
[37] Do not use underscore at the end of variable name Coding Style Informational 3
[38] Use abi.encodeCall() instead of abi.encodeSignature()/abi.encodeSelector() Volatile Code Informational 9
[39] Control structures do not follow the Solidity Style Guide Coding Style Informational 78
[40] Empty Function Body - Consider commenting why Coding Style Informational 1
[41] Reduce gas usage by moving to Solidity 0.8.19 or later Gas Optimization Informational 18
[42] Keccak Constant values should used to immutable rather than constant Coding Style Informational 5
[43] Use block.number instead of block.timestamp Coding Style Informational 4
[44] Use Ownable2StepUpgradeable instead of OwnableUpgradeable contract Control Flow Informational 4
[45] Mark visibility of initialize(...) functions as external Controal Flow Informational 2
[46] Unused State variables Gas Optimization Informational 5
[47] Event is not properly indexed Coding Style Informational 9
[48] public functions not called by the contract should be declared external instead Gas Optimization Informational 15
[49] internal functions not called by the contract should be removed Gas Optimization Informational 17
[50] Cache array length outside of loop Gas Optimization Informational 21
[51] Functions guaranteed to revert when called by normal users can be marked payable Gas Optimization Informational 5
[52] abi.encode() is less efficient than abi.encodepacked() Gas Optimization Informational 4
[53] keccak256() EXPRESSIONS WHICH ARE FIXED, CAN BE PRECALCULATED AND ASSIGNED TO THE CONSTANT VARIABLES. Gas Optimization Informational 5
[54] >= costs less gas than > Gas Optimization Informational 27
[55] ++i costs less gas than i++, especially when it's used in for-loops (--i/i-- too) Gas Optimization Informational 24
[56] x += y/x -= y costs more gas than x = x + y/x = x - y for state variables Gas Optimization Informational 2
[57] Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead Gas Optimization Informational 11
[58] Using private rather than public for constants, saves gas Gas Optimization Informational 12
[59] Don't initialize variables with default value Gas Optimization Informational 23
[60] Inverting the condition of an if-else-statement wastes gas Gas Optimization Informational 4
[61] ++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 Gas Optimization Informational 24
[62] Gas saving is achieved by removing the delete keyword (~60k) Gas Optimization Informational 1
[63] Use != 0 instead of > 0 for unsigned integer comparison Gas Optimization Informational 1
[64] Use shift Right/Left instead of division/multiplication if possible Gas Optimization Informational 3
[65] Constructors can be marked payable Gas Optimization Informational 9
[66] Reduce gas usage by moving to Solidity 0.8.19 or later Gas Optimization Informational 18
[67] Use assembly to hash instead of Solidity Gas Optimization Informational 1
[68] USE BYTES32 INSTEAD OF STRING Gas Optimization Informational 2
[69] Compute known value off-chain Gas Optimization Informational 5
[70] Part of the code can be pre calculated Gas Optimization Informational 5
[71] Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct, where appropriate Gas Optimization Informational 10
[72] Ternary operation is cheaper than if-else statement Gas Optimization Informational 1
[73] Sort Solidity operations using short-circuit mode Gas Optimization Informational 1
[74] Unnecessary cast Gas Optimization Informational 2
[75] Calling .length in a for loop wastes gas Gas Optimization Informational 21
[76] unchecked {} can be used on the division of two uints in order to save gas Gas Optimization Informational 3

M-1 | Centralization Risk for trusted owners

Description :-

Contracts have owners with privileged rights to perform admin tasks and need to be trusted to not perform malicious updates or drain funds.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
126:        onlyRole(

Context:-

SecurityCouncilManager.sol#L126

195:        onlyRole(

Context:-

SecurityCouncilManager.sol#L195

208:        onlyRole(

Context:-

SecurityCouncilManager.sol#L208

273:        onlyRole(

Context:-

SecurityCouncilManager.sol#L273

281:        onlyRole(

Context:-

SecurityCouncilManager.sol#L281

310:        onlyRole(

Context:-

SecurityCouncilManager.sol#L310

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
55:contract L2SecurityCouncilMgmtFactory is Ownable 

Context:-

L2SecurityCouncilMgmtFactory.sol#L55

M-2 | will not work properly on Optimism due to use of block.number

Description :-

When deploying to Optimism, will not be accurate due to the use of block.number.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
151:        if (block.number > vettingDeadline) {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L151

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
152:            revert ProposalNotInVettingPeriod(block.number, vettingDeadline);

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L152

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
333:        if (block.number <= vettingDeadline) {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L333

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
334:            revert ProposalInVettingPeriod(block.number, vettingDeadline);

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L334

L-1 | Initializers could be front-run

Description :-

Initializers could be front-run, allowing an attacker to either set their own values, take ownership of the contract, and in the best case forcing a re-deployment

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
89:    function initialize(

Context:-

SecurityCouncilManager.sol#L89

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
103:    function initialize(

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L103

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
48:    function initialize(

Context:-

SecurityCouncilMemberElectionGovernor.sol#L48

L-2 | Loss of precision

Description :-

Division by large numbers may result in the result being zero, due to solidity not supporting fractions. Consider requiring a minimum amount for the numerator to ensure that it is always larger than the denominator.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
80:        uint256 year = firstNominationStartDate.year + month / 12;

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L80

L-3 | Use safeTransferOwnership instead of transferOwnership function

Description :-

transferOwnership function is used to change Ownership from Ownable.sol. Use a 2 structure transferOwnership which is safer. safeTransferOwnership, use it is more secure due to 2-stage ownership transfer.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
112:        _transferOwnership

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L112

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
66:        _transferOwnership

Context:-

SecurityCouncilMemberElectionGovernor.sol#L66

L-4 | Unbounded loop

Description :-

While looping large collections, it's possible to run out of gas - causing a DOS condition

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
106:for (uint256 i = 0; i < _roles.memberRemovers.length; i++) {

Context:-

SecurityCouncilManager.sol#L106

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
118:for (uint256 i = 0; i < _securityCouncils.length; i++) {

Context:-

SecurityCouncilManager.sol#L118

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
135:for (uint256 i = 0; i < _newCohort.length; i++) {

Context:-

SecurityCouncilManager.sol#L135

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
164:for (uint256 j = 0; j < cohort.length; j++) {

Context:-

SecurityCouncilManager.sol#L164

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
251:for (uint256 i = 0; i < securityCouncils.length; i++) {

Context:-

SecurityCouncilManager.sol#L251

284:for (uint256 i = 0; i < securityCouncils.length; i++) {

Context:-

SecurityCouncilManager.sol#L284

392:for (uint256 i = 0; i < securityCouncils.length; i++) {

Context:-

SecurityCouncilManager.sol#L392

File:governance/src/UpgradeExecRouteBuilder.sol
76:for (uint256 i = 0; i < _upgradeExecutors.length; i++) {

Context:-

UpgradeExecRouteBuilder.sol#L76

File:governance/src/UpgradeExecRouteBuilder.sol
129:for (uint256 i = 0; i < chainIds.length; i++) {

Context:-

UpgradeExecRouteBuilder.sol#L129

193:for (uint256 i = 0; i < chainIds.length; i++) {

Context:-

UpgradeExecRouteBuilder.sol#L193

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
60:for (uint256 i = 0; i < _updatedMembers.length; i++) {

Context:-

SecurityCouncilMemberSyncAction.sol#L60

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
67:for (uint256 i = 0; i < previousOwners.length; i++) {

Context:-

SecurityCouncilMemberSyncAction.sol#L67

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
105:for (uint256 i = 0; i < owners.length; i++) {

Context:-

SecurityCouncilMemberSyncAction.sol#L105

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
6:for (uint256 i = 0; i < arr.length; i++) {

Context:-

SecurityCouncilMgmtUtils.sol#L6

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
22:for (uint256 i = 0; i < input.length; i++) {

Context:-

SecurityCouncilMgmtUtils.sol#L22

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
111:for (uint256 i = 0; i < dp.firstCohort.length; i++) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L111

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
117:for (uint256 i = 0; i < dp.secondCohort.length; i++) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L117

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
61:for (uint256 i = 0; i < array1.length; i++) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L61

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
63:for (uint256 j = 0; j < array2.length; j++) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L63

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
74:for (uint256 i = 0; i < array2.length; i++) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L74

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
76:for (uint256 j = 0; j < array1.length; j++) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L76

L-5 | Use Ownable2Step's transfer function rather than Ownable's for transfers of ownership

Description :-

Ownable2Step and Ownable2StepUpgradeable prevent the contract ownership from mistakenly being transferred to an address that cannot handle it (e.g. due to a typo in the address), by requiring that the recipient of the owner permissions actively accept via a contract call of its own.

Proof Of Concept

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
55:contract L2SecurityCouncilMgmtFactory is Ownable {

Context:-

L2SecurityCouncilMgmtFactory.sol#L55

L-6 | Functions return bool true but cannot return false

Description :-

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
301:return true;

Context:-

SecurityCouncilManager.sol#L301

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
171:return true;

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L171

176:return true;

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L176

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
73:return true;

Context:-

SecurityCouncilMemberSyncAction.sol#L73

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
8:return true;

Context:-

SecurityCouncilMgmtUtils.sol#L8

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
87:return true;

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L87

L-7 | Divide by Zero

Description :-

The divisions below take an input parameter which does not have any zero-value checks, which may lead to the functions reverting when zero is passed.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol
40:            / quorumDenominator();

Context:-

ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L40

L-8 | off-by-one timestamp error

Description :-

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
167:block.timestamp < 

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L167

L-9 | TransferOwnership Should Be Two Step

Description :-

Recommend considering implementing a two step process where the owner or admin nominates an account and the nominated account needs to call an acceptOwnership() function for the transfer of ownership to fully succeed. This ensures the nominated EOA account is a valid and active account.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
112:_transferOwnership(params.owner);

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L112

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
66:_transferOwnership(_owner);

Context:-

SecurityCouncilMemberElectionGovernor.sol#L66

L-10 | Hardcode the address causes no future updates

Description :-

In case the addresses change due to reasons such as updating their versions in the future, addresses coded as constants cannot be updated, so it is recommended to add the update option with the onlyOwner modifier.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
77:    address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;

Context:-

SecurityCouncilManager.sol#L77

File:governance/src/UpgradeExecRouteBuilder.sol
47:    address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;

Context:-

UpgradeExecRouteBuilder.sol#L47

L-11 | abi.encodePacked() should not be used with dynamic types when passing the result to a hash function such as keccak256()

Description :-

Use abi.encode() instead which will pad items to 32 bytes, which will prevent hash collisions (e.g. abi.encodePacked(0x123,0x456) => 0x123456 => abi.encodePacked(0x1,0x23456), but abi.encode(0x123,0x456) => 0x0...1230...456). Unless there is a compelling reason, abi.encode should be preferred. If there is only one argument to abi.encodePacked() it can often be cast to bytes() or bytes32() instead. If all arguments are strings and or bytes, bytes.concat() should be used instead

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
375:keccak256(abi.encodePacked(_members, nonce));

Context:-

SecurityCouncilManager.sol#L375

L-12 | MISSING ZERO ADDRESS VALIDATION

Description :-

Missing checks for zero-addresses may lead to infunctional protocol, if the variable addresses are updated incorrectly

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
248:        nomineeVetter = _nomineeVetter;

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L248

L-13 | For loops in public or external functions should be avoided due to high gas costs and possible DOS

Description :-

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
106:        for (uint256 i = 0; i < _roles.memberRemovers.length; i++) {
107:            _grantRole(MEMBER_REMOVER_ROLE, _roles.memberRemovers[i]);
108:        }

Context:-

SecurityCouncilManager.sol#L106-L108

118:        for (uint256 i = 0; i < _securityCouncils.length; i++) {
119:            _addSecurityCouncil(_securityCouncils[i]);
120:        }

Context:-

SecurityCouncilManager.sol#L118-L120

135:        for (uint256 i = 0; i < _newCohort.length; i++) {
136:            _addMemberToCohortArray(_newCohort[i], _cohort);
137:        }

Context:-

SecurityCouncilManager.sol#L135-L137

284:        for (uint256 i = 0; i < securityCouncils.length; i++) {
285:            SecurityCouncilData storage securityCouncilData = securityCouncils[i];
286:            if (
287:                securityCouncilData.securityCouncil == _securityCouncilData.securityCouncil
288:                    && securityCouncilData.chainId == _securityCouncilData.chainId
289:                    && securityCouncilData.updateAction == _securityCouncilData.updateAction
290:            ) {
291:                SecurityCouncilData storage lastSecurityCouncil =
292:                    securityCouncils[securityCouncils.length - 1];
293:
294:                securityCouncils[i] = lastSecurityCouncil;
295:                securityCouncils.pop();
296:                emit SecurityCouncilRemoved(
297:                    securityCouncilData.securityCouncil,
298:                    securityCouncilData.updateAction,
299:                    securityCouncils.length
300:                );
301:                return true;
302:            }
303:        }

Context:-

SecurityCouncilManager.sol#L284-L303

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
60:        for (uint256 i = 0; i < _updatedMembers.length; i++) {
61:            address member = _updatedMembers[i];
62:            if (!securityCouncil.isOwner(member)) {
63:                _addMember(securityCouncil, member, threshold);
64:            }
65:        }

Context:-

SecurityCouncilMemberSyncAction.sol#L60-L65

67:        for (uint256 i = 0; i < previousOwners.length; i++) {
68:            address owner = previousOwners[i];
69:            if (!SecurityCouncilMgmtUtils.isInArray(owner, _updatedMembers)) {
70:                _removeMember(securityCouncil, owner, threshold);
71:            }
72:        }

Context:-

SecurityCouncilMemberSyncAction.sol#L67-L72

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
111:        for (uint256 i = 0; i < dp.firstCohort.length; i++) {
112:            if (!govChainEmergencySCSafe.isOwner(dp.firstCohort[i])) {
113:                revert AddressNotInCouncil(owners, dp.firstCohort[i]);
114:            }
115:        }

Context:-

L2SecurityCouncilMgmtFactory.sol#L111-L115

117:        for (uint256 i = 0; i < dp.secondCohort.length; i++) {
118:            if (!govChainEmergencySCSafe.isOwner(dp.secondCohort[i])) {
119:                revert AddressNotInCouncil(owners, dp.secondCohort[i]);
120:            }
121:        }

Context:-

L2SecurityCouncilMgmtFactory.sol#L117-L121

L-14 | Lack of Storage Gap

Description :-

The contracts in scope are intended to be the implementation (logic) contracts behind certain proxy contract. Implementation contracts should have a storage gap to allow for upgradeability / adding new variables in future upgrades, which are missing in these contracts. If not careful, new variables added in a child contract could accidentally overwrite variables in its parent contract.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
23:    OwnableUpgradeable,

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L23

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
23:    OwnableUpgradeable,

Context:-

SecurityCouncilMemberElectionGovernor.sol#L23

L-15 | Unprotected Initializer

Description :-

One or more logic contracts do not protect their initializers. An attacker can call the initializer and assume ownership of the logic contract, whereby she can perform privileged operations that trick unsuspecting users into believing that she is the owner of the upgradeable contract.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
89:    function initialize(
90:        address[] memory _firstCohort,
91:        address[] memory _secondCohort,
92:        SecurityCouncilData[] memory _securityCouncils,
93:        SecurityCouncilManagerRoles memory _roles,
94:        address payable _l2CoreGovTimelock,
95:        UpgradeExecRouteBuilder _router
96:    ) external initializer {
97:        if (_firstCohort.length != _secondCohort.length) {
98:            revert CohortLengthMismatch(_firstCohort, _secondCohort);
99:        }
100:        firstCohort = _firstCohort;
101:        secondCohort = _secondCohort;
102:        cohortSize = _firstCohort.length;
103:        _grantRole(DEFAULT_ADMIN_ROLE, _roles.admin);
104:        _grantRole(COHORT_REPLACER_ROLE, _roles.cohortUpdator);
105:        _grantRole(MEMBER_ADDER_ROLE, _roles.memberAdder);
106:        for (uint256 i = 0; i < _roles.memberRemovers.length; i++) {
107:            _grantRole(MEMBER_REMOVER_ROLE, _roles.memberRemovers[i]);
108:        }
109:        _grantRole(MEMBER_ROTATOR_ROLE, _roles.memberRotator);
110:        _grantRole(MEMBER_REPLACER_ROLE, _roles.memberReplacer);
111:
112:        if (!Address.isContract(_l2CoreGovTimelock)) {
113:            revert NotAContract({account: _l2CoreGovTimelock});
114:        }
115:        l2CoreGovTimelock = _l2CoreGovTimelock;
116:
117:        _setUpgradeExecRouteBuilder(_router);
118:        for (uint256 i = 0; i < _securityCouncils.length; i++) {
119:            _addSecurityCouncil(_securityCouncils[i]);
120:        }
121:    }

Context:-

SecurityCouncilManager.sol#L89-L121

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
103:    function initialize(InitParams memory params) public initializer {
104:        __Governor_init("SecurityCouncilNomineeElectionGovernor");
105:        __GovernorVotes_init(params.token);
106:        __SecurityCouncilNomineeElectionGovernorCounting_init();
107:        __ArbitrumGovernorVotesQuorumFraction_init(params.quorumNumeratorValue);
108:        __GovernorSettings_init(0, params.votingPeriod, 0); // votingDelay and proposalThreshold are set to 0
109:        __SecurityCouncilNomineeElectionGovernorTiming_init(
110:            params.firstNominationStartDate, params.nomineeVettingDuration
111:        );
112:        _transferOwnership(params.owner);
113:
114:        nomineeVetter = params.nomineeVetter;
115:        if (!Address.isContract(address(params.securityCouncilManager))) {
116:            revert NotAContract(address(params.securityCouncilManager));
117:        }
118:        securityCouncilManager = params.securityCouncilManager;
119:        if (!Address.isContract(address(params.securityCouncilMemberElectionGovernor))) {
120:            revert NotAContract(address(params.securityCouncilMemberElectionGovernor));
121:        }
122:        securityCouncilMemberElectionGovernor = params.securityCouncilMemberElectionGovernor;
123:
124:        // elsewhere we make assumptions that the number of nominees
125:        // is not greater than 500
126:        // This value can still be updated via updateQuorumNumerator to a lower value
127:        // if it is deemed ok, however we put a quick check here as a reminder
128:        if ((quorumDenominator() / params.quorumNumeratorValue) > 500) {
129:            revert QuorumNumeratorTooLow(params.quorumNumeratorValue);
130:        }
131:    }

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L103-L131

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
48:    function initialize(
49:        ISecurityCouncilNomineeElectionGovernor _nomineeElectionGovernor,
50:        ISecurityCouncilManager _securityCouncilManager,
51:        IVotesUpgradeable _token,
52:        address _owner,
53:        uint256 _votingPeriod,
54:        uint256 _fullWeightDuration
55:    ) public initializer {
56:        if (_fullWeightDuration > _votingPeriod) {
57:            revert InvalidDurations(_fullWeightDuration, _votingPeriod);
58:        }
59:
60:        __Governor_init("SecurityCouncilMemberElectionGovernor");
61:        __GovernorVotes_init(_token);
62:        __SecurityCouncilMemberElectionGovernorCounting_init({
63:            initialFullWeightDuration: _fullWeightDuration
64:        });
65:        __GovernorSettings_init(0, _votingPeriod, 0);
66:        _transferOwnership(_owner);
67:
68:        if (!Address.isContract(address(_nomineeElectionGovernor))) {
69:            revert NotAContract(address(_nomineeElectionGovernor));
70:        }
71:        nomineeElectionGovernor = _nomineeElectionGovernor;
72:        if (!Address.isContract(address(_securityCouncilManager))) {
73:            revert NotAContract(address(_securityCouncilManager));
74:        }
75:        securityCouncilManager = _securityCouncilManager;
76:    }

Context:-

SecurityCouncilMemberElectionGovernor.sol#L48-L76

NC-1 | Functions guaranteed to revert when called by normal users can be marked payable

Description :-

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.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
176:function addMember(address _newMember, Cohort _cohort) external onlyRole(MEMBER_ADDER_ROLE) {

Context:-

SecurityCouncilManager.sol#L176

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
183:function removeMember(address _member) external onlyRole(MEMBER_REMOVER_ROLE) {

Context:-

SecurityCouncilManager.sol#L183

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
246:function setNomineeVetter(address _nomineeVetter) external onlyGovernance {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L246

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
290:function includeNominee(uint256 proposalId, address account) external onlyNomineeVetter {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L290

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
52:function __SecurityCouncilNomineeElectionGovernorCounting_init() internal onlyInitializing {}

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L52

NC-2 | Imports could be organized more systematically

Description :-

The contract's interface should be imported first, followed by each of the interfaces it uses, followed by all other files. The examples below do not follow this layout.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
4:import "../ArbitrumTimelock.sol";

Context:-

SecurityCouncilManager.sol#L4

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
5:import "../UpgradeExecutor.sol";

Context:-

SecurityCouncilManager.sol#L5

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
6:import "../L1ArbitrumTimelock.sol";

Context:-

SecurityCouncilManager.sol#L6

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
7:import "./SecurityCouncilMgmtUtils.sol";

Context:-

SecurityCouncilManager.sol#L7

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
8:import "./interfaces/ISecurityCouncilManager.sol";

Context:-

SecurityCouncilManager.sol#L8

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
9:import "./SecurityCouncilMemberSyncAction.sol";

Context:-

SecurityCouncilManager.sol#L9

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
10:import "../UpgradeExecRouteBuilder.sol";

Context:-

SecurityCouncilManager.sol#L10

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
11:import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

Context:-

SecurityCouncilManager.sol#L11

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
12:import "@openzeppelin/contracts/utils/Address.sol";

Context:-

SecurityCouncilManager.sol#L12

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
13:import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";

Context:-

SecurityCouncilManager.sol#L13

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
14:import "./Common.sol";

Context:-

SecurityCouncilManager.sol#L14

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
4:import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol";

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L4

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
5:import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L5

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
6:import "../interfaces/ISecurityCouncilMemberElectionGovernor.sol";

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L6

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
7:import "../interfaces/ISecurityCouncilNomineeElectionGovernor.sol";

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L7

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
8:import "./modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol";

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L8

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
9:import "./modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol";

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L9

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
10:import "./modules/SecurityCouncilNomineeElectionGovernorTiming.sol";

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L10

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
11:import "./modules/ElectionGovernor.sol";

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L11

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
12:import "../SecurityCouncilMgmtUtils.sol";

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L12

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
4:import "@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol";

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L4

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
4:import "../../interfaces/ISecurityCouncilManager.sol";

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L4

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
6:import "@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol";

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L6

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
7:import "solady/utils/DateTimeLib.sol";

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L7

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
8:import "../../Common.sol";

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L8

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
4:import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol";

Context:-

SecurityCouncilMemberElectionGovernor.sol#L4

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
5:import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol";

Context:-

SecurityCouncilMemberElectionGovernor.sol#L5

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
6:import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

Context:-

SecurityCouncilMemberElectionGovernor.sol#L6

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
7:import "./modules/SecurityCouncilMemberElectionGovernorCountingUpgradeable.sol";

Context:-

SecurityCouncilMemberElectionGovernor.sol#L7

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
8:import "../interfaces/ISecurityCouncilMemberElectionGovernor.sol";

Context:-

SecurityCouncilMemberElectionGovernor.sol#L8

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
9:import "../interfaces/ISecurityCouncilNomineeElectionGovernor.sol";

Context:-

SecurityCouncilMemberElectionGovernor.sol#L9

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
10:import "../interfaces/ISecurityCouncilManager.sol";

Context:-

SecurityCouncilMemberElectionGovernor.sol#L10

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
11:import "./modules/ElectionGovernor.sol";

Context:-

SecurityCouncilMemberElectionGovernor.sol#L11

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
5:import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";

Context:-

ElectionGovernor.sol#L5

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
6:import "../../Common.sol";

Context:-

ElectionGovernor.sol#L6

File:governance/src/UpgradeExecRouteBuilder.sol
4:import "@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";

Context:-

UpgradeExecRouteBuilder.sol#L4

File:governance/src/UpgradeExecRouteBuilder.sol
5:import "./UpgradeExecutor.sol";

Context:-

UpgradeExecRouteBuilder.sol#L5

File:governance/src/UpgradeExecRouteBuilder.sol
6:import "./L1ArbitrumTimelock.sol";

Context:-

UpgradeExecRouteBuilder.sol#L6

File:governance/src/UpgradeExecRouteBuilder.sol
7:import "./security-council-mgmt/Common.sol";

Context:-

UpgradeExecRouteBuilder.sol#L7

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
4:import "./interfaces/IGnosisSafe.sol";

Context:-

SecurityCouncilMemberSyncAction.sol#L4

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
5:import "./SecurityCouncilMgmtUtils.sol";

Context:-

SecurityCouncilMemberSyncAction.sol#L5

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
6:import "../gov-action-contracts/execution-record/ActionExecutionRecord.sol";

Context:-

SecurityCouncilMemberSyncAction.sol#L6

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
4:import "@openzeppelin/contracts/access/Ownable.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L4

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
5:import "@openzeppelin/contracts/utils/Address.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L5

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
6:import "../governors/SecurityCouncilMemberElectionGovernor.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L6

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
7:import "../governors/SecurityCouncilNomineeElectionGovernor.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L7

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
8:import "../SecurityCouncilManager.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L8

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
9:import "../governors/SecurityCouncilMemberRemovalGovernor.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L9

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
10:import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L10

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
11:import "../interfaces/ISecurityCouncilManager.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L11

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
12:import "../interfaces/IGnosisSafe.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L12

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
13:import "../../ArbitrumTimelock.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L13

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
14:import "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L14

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
15:import "../../UpgradeExecRouteBuilder.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L15

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
16:import "../Common.sol";

Context:-

L2SecurityCouncilMgmtFactory.sol#L16

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
4:import "../../../security-council-mgmt/interfaces/IGnosisSafe.sol";

Context:-

GovernanceChainSCMgmtActivationAction.sol#L4

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
5:import "../../address-registries/L2AddressRegistryInterfaces.sol";

Context:-

GovernanceChainSCMgmtActivationAction.sol#L5

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
6:import "./SecurityCouncilMgmtUpgradeLib.sol";

Context:-

GovernanceChainSCMgmtActivationAction.sol#L6

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
7:import "../../../interfaces/IArbitrumDAOConstitution.sol";

Context:-

GovernanceChainSCMgmtActivationAction.sol#L7

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
8:import "../../../interfaces/IUpgradeExecutor.sol";

Context:-

GovernanceChainSCMgmtActivationAction.sol#L8

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
9:import "../../../interfaces/ICoreTimelock.sol";

Context:-

GovernanceChainSCMgmtActivationAction.sol#L9

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
10:import "@openzeppelin/contracts/utils/Address.sol";

Context:-

GovernanceChainSCMgmtActivationAction.sol#L10

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
4:import "../../../security-council-mgmt/interfaces/IGnosisSafe.sol";

Context:-

L1SCMgmtActivationAction.sol#L4

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
5:import "../../../interfaces/IUpgradeExecutor.sol";

Context:-

L1SCMgmtActivationAction.sol#L5

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
6:import "../../../interfaces/ICoreTimelock.sol";

Context:-

L1SCMgmtActivationAction.sol#L6

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
7:import "./SecurityCouncilMgmtUpgradeLib.sol";

Context:-

L1SCMgmtActivationAction.sol#L7

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol
4:import "../../../security-council-mgmt/interfaces/IGnosisSafe.sol";

Context:-

NonGovernanceChainSCMgmtActivationAction.sol#L4

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol
5:import "./SecurityCouncilMgmtUpgradeLib.sol";

Context:-

NonGovernanceChainSCMgmtActivationAction.sol#L5

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
4:import "../../../security-council-mgmt/interfaces/IGnosisSafe.sol";

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L4

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
5:import "../../../interfaces/IUpgradeExecutor.sol";

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L5

File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol
4:import "./KeyValueStore.sol";

Context:-

ActionExecutionRecord.sol#L4

NC-3 | Use a more recent version of solidity

Description :-

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilManager.sol#L2

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L2

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L2

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L2

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilMemberElectionGovernor.sol#L2

File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol
2:pragma solidity 0.8.16;

Context:-

ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L2

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
3:pragma solidity 0.8.16;

Context:-

ElectionGovernor.sol#L3

File:governance/src/UpgradeExecRouteBuilder.sol
2:pragma solidity 0.8.16;

Context:-

UpgradeExecRouteBuilder.sol#L2

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilMemberSyncAction.sol#L2

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilMgmtUtils.sol#L2

File:governance/src/security-council-mgmt/Common.sol
2:pragma solidity 0.8.16;

Context:-

Common.sol#L2

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
2:pragma solidity 0.8.16;

Context:-

L2SecurityCouncilMgmtFactory.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
2:pragma solidity 0.8.16;

Context:-

GovernanceChainSCMgmtActivationAction.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
2:pragma solidity 0.8.16;

Context:-

L1SCMgmtActivationAction.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol
2:pragma solidity 0.8.16;

Context:-

NonGovernanceChainSCMgmtActivationAction.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L2

File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol
2:pragma solidity 0.8.16;

Context:-

KeyValueStore.sol#L2

File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol
2:pragma solidity 0.8.16;

Context:-

ActionExecutionRecord.sol#L2

NC-4 | Consider using delete rather than assigning zero to clear values

Description :-

The delete keyword more closely matches the semantics of what is being done, and draws more attention to the changing of state, which may lead to a more thorough audit of its associated logic

Proof Of Concept

File:governance/src/UpgradeExecRouteBuilder.sol
150:                schedValues[i] = 0;

Context:-

UpgradeExecRouteBuilder.sol#L150

NC-5 | Use of bytes.concat() instead of abi.encodePacked()

Description :-

Since version 0.8.4 for appending bytes, bytes.concat() can be used instead of abi.encodePacked(,)

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
375:        return keccak256(abi.encodePacked(_members, nonce));

Context:-

SecurityCouncilManager.sol#L375

NC-6 | Variables need not be initialized to zero

Description :-

The default value for variables is zero, so initializing them to zero is superfluous.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
106:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L106

118:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L118

135:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L135

162:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L162

251:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L251

284:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L284

339:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L339

342:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L342

392:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L392

File:governance/src/UpgradeExecRouteBuilder.sol
52:uint256 public constant DEFAULT_VALUE = 0;

Context:-

UpgradeExecRouteBuilder.sol#L52

File:governance/src/UpgradeExecRouteBuilder.sol
76:uint256 i = 0;

Context:-

UpgradeExecRouteBuilder.sol#L76

129:uint256 i = 0;

Context:-

UpgradeExecRouteBuilder.sol#L129

193:uint256 i = 0;

Context:-

UpgradeExecRouteBuilder.sol#L193

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
60:uint256 i = 0;

Context:-

SecurityCouncilMemberSyncAction.sol#L60

67:uint256 i = 0;

Context:-

SecurityCouncilMemberSyncAction.sol#L67

105:uint256 i = 0;

Context:-

SecurityCouncilMemberSyncAction.sol#L105

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
6:uint256 i = 0;

Context:-

SecurityCouncilMgmtUtils.sol#L6

22:uint256 i = 0;

Context:-

SecurityCouncilMgmtUtils.sol#L22

31:uint256 i = 0;

Context:-

SecurityCouncilMgmtUtils.sol#L31

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
111:uint256 i = 0;

Context:-

L2SecurityCouncilMgmtFactory.sol#L111

117:uint256 i = 0;

Context:-

L2SecurityCouncilMgmtFactory.sol#L117

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
61:uint256 i = 0;

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L61

74:uint256 i = 0;

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L74

NC-7 | Use a single file for all system-wide constants

Description :-

Consider defining in only one contract so that values cannot become out of sync when only one location is updated. A cheap way to store constants in a single location is to create an internal constant in a library. If the variable is a local cache of another contract’s value, consider making the cache variable internal or private, which will require external users to query the contract with the source of truth, so that callers don’t get out of sync.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
77:    address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;

Context:-

SecurityCouncilManager.sol#L77

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
79:    bytes32 public constant COHORT_REPLACER_ROLE = keccak256("COHORT_REPLACER");

Context:-

SecurityCouncilManager.sol#L79

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
80:    bytes32 public constant MEMBER_ADDER_ROLE = keccak256("MEMBER_ADDER");

Context:-

SecurityCouncilManager.sol#L80

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
81:    bytes32 public constant MEMBER_REPLACER_ROLE = keccak256("MEMBER_REPLACER");

Context:-

SecurityCouncilManager.sol#L81

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
82:    bytes32 public constant MEMBER_ROTATOR_ROLE = keccak256("MEMBER_ROTATOR");

Context:-

SecurityCouncilManager.sol#L82

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
83:    bytes32 public constant MEMBER_REMOVER_ROLE = keccak256("MEMBER_REMOVER");

Context:-

SecurityCouncilManager.sol#L83

File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol
22:    address public constant EXCLUDE_ADDRESS = address(0xA4b86);

Context:-

ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L22

File:governance/src/UpgradeExecRouteBuilder.sol
47:    address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;

Context:-

UpgradeExecRouteBuilder.sol#L47

File:governance/src/UpgradeExecRouteBuilder.sol
52:    uint256 public constant DEFAULT_VALUE = 0;

Context:-

UpgradeExecRouteBuilder.sol#L52

File:governance/src/UpgradeExecRouteBuilder.sol
54:    bytes32 public constant DEFAULT_PREDECESSOR = bytes32(0);

Context:-

UpgradeExecRouteBuilder.sol#L54

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
19:    address public constant SENTINEL_OWNERS = address(0x1);

Context:-

SecurityCouncilMemberSyncAction.sol#L19

NC-8 | Not using the named return variables anywhere in the function is confusing

Description :-

Consider changing the variable to be an unnamed one, since the variable is never assigned, nor is it returned by name. If the optimizer is not turned on, leaving the code as it is will also waste gas for the stack variable.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
415:  return (newMembers, to, data);

Context:-

SecurityCouncilManager.sol#L415

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
396:  return (electionCount < 2) ? Cohort.SECOND : electionIndexToCohort(electionCount - 2);

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L396

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
401:  return _elections[proposalId].isExcluded[possibleExcluded];

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L401

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
406:  return _elections[proposalId].excludedNomineeCount;

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L406

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
417:  return _elections[proposalId].isContender[possibleContender];

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L417

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
134:  return _elections[proposalId].votesUsed[account] > 0;

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L134

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
139:  return _elections[proposalId].isNominee[contender];

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L139

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
144:  return _elections[proposalId].nominees.length;

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L144

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
149:  return _elections[proposalId].nominees;

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L149

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
154:  return _elections[proposalId].votesUsed[account];

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L154

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
159:  return _elections[proposalId].votesReceived[contender];

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L159

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
24:  return (

Context:-

ElectionGovernor.sol#L24

File:governance/src/UpgradeExecRouteBuilder.sol
174:  return (

Context:-

UpgradeExecRouteBuilder.sol#L174

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
119:  return _get(uint160(securityCouncil));

Context:-

SecurityCouncilMemberSyncAction.sol#L119

File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol
17:  return _get(msg.sender, key);

Context:-

KeyValueStore.sol#L17

File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol
22:  return _get(owner, key);

Context:-

KeyValueStore.sol#L22

NC-9 | Unsigned divisions can be marked as unchecked

Description :-

Divisions which do not divide by -1 cannot overflow or overflow so such operations can be unchecked to save gas

Proof Of Concept

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
80:uint256 year = firstNominationStartDate.year + month / 12;

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L80

NC-10 | Non-external/public function names should begin with an underscore

Description :-

According to the Solidity Style Guide, Non-external/public variable and function names should begin with an underscore

Proof Of Concept

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
34:function extractElectionIndex(bytes[] memory callDatas) internal pure returns (uint256) {

Context:-

ElectionGovernor.sol#L34

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
5:function isInArray(address addr, address[] memory arr) internal pure returns (bool) {

Context:-

SecurityCouncilMgmtUtils.sol#L5

NC-11 | Uppercase immutable variables

Description :-

Variable does not follow Solidity naming best pratices

Proof Of Concept

File:governance/src/UpgradeExecRouteBuilder.sol
57:    address public immutable l1TimelockAddr;

Context:-

UpgradeExecRouteBuilder.sol#L57

File:governance/src/UpgradeExecRouteBuilder.sol
60:    uint256 public immutable l1TimelockMinDelay;

Context:-

UpgradeExecRouteBuilder.sol#L60

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
13:    IGnosisSafe public immutable newEmergencySecurityCouncil;

Context:-

GovernanceChainSCMgmtActivationAction.sol#L13

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
14:    IGnosisSafe public immutable newNonEmergencySecurityCouncil;

Context:-

GovernanceChainSCMgmtActivationAction.sol#L14

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
16:    IGnosisSafe public immutable prevEmergencySecurityCouncil;

Context:-

GovernanceChainSCMgmtActivationAction.sol#L16

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
17:    IGnosisSafe public immutable prevNonEmergencySecurityCouncil;

Context:-

GovernanceChainSCMgmtActivationAction.sol#L17

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
19:    uint256 public immutable emergencySecurityCouncilThreshold;

Context:-

GovernanceChainSCMgmtActivationAction.sol#L19

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
20:    uint256 public immutable nonEmergencySecurityCouncilThreshold;

Context:-

GovernanceChainSCMgmtActivationAction.sol#L20

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
22:    address public immutable securityCouncilManager;

Context:-

GovernanceChainSCMgmtActivationAction.sol#L22

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
23:    IL2AddressRegistry public immutable l2AddressRegistry;

Context:-

GovernanceChainSCMgmtActivationAction.sol#L23

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
10:    IGnosisSafe public immutable newEmergencySecurityCouncil;

Context:-

L1SCMgmtActivationAction.sol#L10

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
11:    IGnosisSafe public immutable prevEmergencySecurityCouncil;

Context:-

L1SCMgmtActivationAction.sol#L11

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
12:    uint256 public immutable emergencySecurityCouncilThreshold;

Context:-

L1SCMgmtActivationAction.sol#L12

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
13:    IUpgradeExecutor public immutable l1UpgradeExecutor;

Context:-

L1SCMgmtActivationAction.sol#L13

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
14:    ICoreTimelock public immutable l1Timelock;

Context:-

L1SCMgmtActivationAction.sol#L14

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol
8:    IGnosisSafe public immutable newEmergencySecurityCouncil;

Context:-

NonGovernanceChainSCMgmtActivationAction.sol#L8

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol
9:    IGnosisSafe public immutable prevEmergencySecurityCouncil;

Context:-

NonGovernanceChainSCMgmtActivationAction.sol#L9

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol
10:    uint256 public immutable emergencySecurityCouncilThreshold;

Context:-

NonGovernanceChainSCMgmtActivationAction.sol#L10

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol
11:    IUpgradeExecutor public immutable upgradeExecutor;

Context:-

NonGovernanceChainSCMgmtActivationAction.sol#L11

File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol
13:    KeyValueStore public immutable store;

Context:-

ActionExecutionRecord.sol#L13

File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol
16:    bytes32 public immutable actionContractId;

Context:-

ActionExecutionRecord.sol#L16

NC-12 | block.timestamp used as time proxy

Description :-

block.timestamp is not an ideal proxy for time because of issues with synchronization, miner manipulation and changing block times.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
167:        if (block.timestamp < thisElectionStartTs) {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L167

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
168:            revert CreateTooEarly(block.timestamp, thisElectionStartTs);

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L168

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
60:        if (startTimestamp <= block.timestamp) {

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L60

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
61:            revert StartDateTooEarly(startTimestamp, block.timestamp);

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L61

NC-13 | Interfaces should be indicated with an I prefix in the contract name.

Description :-

Consider renaming to camelCase

Proof Of Concept

File:governance/src/UpgradeExecRouteBuilder.sol
9:interface DefaultGovAction {

Context:-

UpgradeExecRouteBuilder.sol#L9

NC-14 | Consider using named mappings

Description :-

Consider moving to solidity version 0.8.18 or later, and using named mappings to make it easier to understand the purpose of each mapping.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
26:mapping(uint256 => NomineeElectionCountingInfo) private _elections;

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L26

File:governance/src/UpgradeExecRouteBuilder.sol
62:mapping(uint256 => UpExecLocation) public upExecLocations;

Context:-

UpgradeExecRouteBuilder.sol#L62

File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol
7:mapping(uint256 => uint256) public store;

Context:-

KeyValueStore.sol#L7

NC-15 | Consider disabling renounceOwnership()

Description :-

If the plan for your project does not include eventually giving up all ownership control, consider overwriting OpenZeppelin's Ownable's renounceOwnership() function in order to disable it.

Proof Of Concept

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
55:contract L2SecurityCouncilMgmtFactory is Ownable 

Context:-

L2SecurityCouncilMgmtFactory.sol#L55

NC-16 | addresss shouldn't be hard-coded

Description :-

It is often better to declare addresses as immutable, and assign them via constructor arguments. This allows the code to remain the same across deployments on different networks, and avoids recompilation when addresses need to change.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
77:    address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;

Context:-

SecurityCouncilManager.sol#L77

File:governance/src/UpgradeExecRouteBuilder.sol
47:    address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;

Context:-

UpgradeExecRouteBuilder.sol#L47

NC-17 | Interfaces should be defined in separate files from their usage

Description :-

The interfaces below should be defined in separate files, so that it's easier for future projects to import them, and to avoid duplication later on if they need to be used elsewhere in the project

Proof Of Concept

File:governance/src/UpgradeExecRouteBuilder.sol
9:interface DefaultGovAction {

Context:-

UpgradeExecRouteBuilder.sol#L9

NC-18 | Use replace and pop instead of the delete keyword to removing an item from an array

Description :-

Instead of setting an value with zero (using the delete keyword), a better approach for removing an asset can be to replace the target item with the last element and pop the last element

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
133:delete firstCohort : delete secondCohort;

Context:-

SecurityCouncilManager.sol#L133

NC-19 | Consider bounding input array length

Description :-

The functions below take in an unbounded array, and make function calls for entries in the array. While the function will revert if it eventually runs out of gas, it may be a nicer user experience to require() that the length of the array is below some reasonable maximum, so that the user doesn't have to use up a full transaction's gas only to see that the transaction reverts.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
106:for (uint256 i = 0; i < _roles.memberRemovers.length; i++)

Context:-

SecurityCouncilManager.sol#L106

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
118:for (uint256 i = 0; i < _securityCouncils.length; i++)

Context:-

SecurityCouncilManager.sol#L118

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
135:for (uint256 i = 0; i < _newCohort.length; i++)

Context:-

SecurityCouncilManager.sol#L135

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
164:for (uint256 j = 0; j < cohort.length; j++)

Context:-

SecurityCouncilManager.sol#L164

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
251:for (uint256 i = 0; i < securityCouncils.length; i++)

Context:-

SecurityCouncilManager.sol#L251

284:for (uint256 i = 0; i < securityCouncils.length; i++)

Context:-

SecurityCouncilManager.sol#L284

392:for (uint256 i = 0; i < securityCouncils.length; i++)

Context:-

SecurityCouncilManager.sol#L392

File:governance/src/UpgradeExecRouteBuilder.sol
76:for (uint256 i = 0; i < _upgradeExecutors.length; i++)

Context:-

UpgradeExecRouteBuilder.sol#L76

File:governance/src/UpgradeExecRouteBuilder.sol
129:for (uint256 i = 0; i < chainIds.length; i++)

Context:-

UpgradeExecRouteBuilder.sol#L129

193:for (uint256 i = 0; i < chainIds.length; i++)

Context:-

UpgradeExecRouteBuilder.sol#L193

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
60:for (uint256 i = 0; i < _updatedMembers.length; i++)

Context:-

SecurityCouncilMemberSyncAction.sol#L60

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
67:for (uint256 i = 0; i < previousOwners.length; i++)

Context:-

SecurityCouncilMemberSyncAction.sol#L67

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
105:for (uint256 i = 0; i < owners.length; i++)

Context:-

SecurityCouncilMemberSyncAction.sol#L105

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
6:for (uint256 i = 0; i < arr.length; i++)

Context:-

SecurityCouncilMgmtUtils.sol#L6

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
22:for (uint256 i = 0; i < input.length; i++)

Context:-

SecurityCouncilMgmtUtils.sol#L22

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
111:for (uint256 i = 0; i < dp.firstCohort.length; i++)

Context:-

L2SecurityCouncilMgmtFactory.sol#L111

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
117:for (uint256 i = 0; i < dp.secondCohort.length; i++)

Context:-

L2SecurityCouncilMgmtFactory.sol#L117

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
61:for (uint256 i = 0; i < array1.length; i++)

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L61

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
63:for (uint256 j = 0; j < array2.length; j++)

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L63

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
74:for (uint256 i = 0; i < array2.length; i++)

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L74

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
76:for (uint256 j = 0; j < array1.length; j++)

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L76

NC-20 | Do not use underscore at the end of variable name

Description :-

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
144:        ProposalState state_ 

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L144

225:        ProposalState state_ 

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L225

291:        ProposalState state_ 

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L291

NC-21 | Use abi.encodeCall() instead of abi.encodeSignature()/abi.encodeSelector()

Description :-

abi.encodeCall() has compiler type safety, whereas the other two functions do not

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
396:abi.encodeWithSelector(

Context:-

SecurityCouncilManager.sol#L396

File:governance/src/UpgradeExecRouteBuilder.sol
51:abi.encodeWithSelector(DefaultGovAction.perform.selector);

Context:-

UpgradeExecRouteBuilder.sol#L51

File:governance/src/UpgradeExecRouteBuilder.sol
51:abi.encodeWithSelector(

Context:-

UpgradeExecRouteBuilder.sol#L51

138:abi.encodeWithSelector(

Context:-

UpgradeExecRouteBuilder.sol#L138

163:abi.encodeWithSelector(

Context:-

UpgradeExecRouteBuilder.sol#L163

176:abi.encodeWithSelector(

Context:-

UpgradeExecRouteBuilder.sol#L176

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
81:abi.encodeWithSelector(IGnosisSafe.addOwnerWithThreshold.selector, _member, _threshold)

Context:-

SecurityCouncilMemberSyncAction.sol#L81

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
81:abi.encodeWithSelector(

Context:-

SecurityCouncilMemberSyncAction.sol#L81

91:abi.encodeWithSelector(

Context:-

SecurityCouncilMemberSyncAction.sol#L91

NC-22 | Control structures do not follow the Solidity Style Guide

Description :-

See the control structures section of the Solidity Style Guide

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
97:        if (_firstCohort.length != _secondCohort.length) {

Context:-

SecurityCouncilManager.sol#L97

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
112:        if (!Address.isContract(_l2CoreGovTimelock)) {

Context:-

SecurityCouncilManager.sol#L112

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
128:        if (_newCohort.length != cohortSize) {

Context:-

SecurityCouncilManager.sol#L128

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
144:        if (_newMember == address(0)) {

Context:-

SecurityCouncilManager.sol#L144

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
148:        if (cohort.length == cohortSize) {

Context:-

SecurityCouncilManager.sol#L148

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
151:        if (firstCohortIncludes(_newMember)) {

Context:-

SecurityCouncilManager.sol#L151

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
154:        if (secondCohortIncludes(_newMember)) {

Context:-

SecurityCouncilManager.sol#L154

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
165:                if (_member == cohort[j]) {

Context:-

SecurityCouncilManager.sol#L165

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
184:        if (_member == address(0)) {

Context:-

SecurityCouncilManager.sol#L184

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
222:        if (_addressToRemove == address(0) || _addressToAdd == address(0)) {

Context:-

SecurityCouncilManager.sol#L222

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
232:        if (securityCouncils.length == MAX_SECURITY_COUNCILS) {

Context:-

SecurityCouncilManager.sol#L232

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
97:        if (

Context:-

SecurityCouncilManager.sol#L97

112:        if (

Context:-

SecurityCouncilManager.sol#L112

128:        if (

Context:-

SecurityCouncilManager.sol#L128

144:        if (

Context:-

SecurityCouncilManager.sol#L144

148:        if (

Context:-

SecurityCouncilManager.sol#L148

151:        if (

Context:-

SecurityCouncilManager.sol#L151

154:        if (

Context:-

SecurityCouncilManager.sol#L154

165:        if (

Context:-

SecurityCouncilManager.sol#L165

184:        if (

Context:-

SecurityCouncilManager.sol#L184

222:        if (

Context:-

SecurityCouncilManager.sol#L222

232:        if (

Context:-

SecurityCouncilManager.sol#L232

236:        if (

Context:-

SecurityCouncilManager.sol#L236

243:        if (

Context:-

SecurityCouncilManager.sol#L243

247:        if (

Context:-

SecurityCouncilManager.sol#L247

254:        if (

Context:-

SecurityCouncilManager.sol#L254

286:        if (

Context:-

SecurityCouncilManager.sol#L286

318:        if (

Context:-

SecurityCouncilManager.sol#L318

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
115:        if (!Address.isContract(address(params.securityCouncilManager))) {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L115

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
119:        if (!Address.isContract(address(params.securityCouncilMemberElectionGovernor))) {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L119

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
128:        if ((quorumDenominator() / params.quorumNumeratorValue) > 500) {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L128

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
135:        if (msg.sender != nomineeVetter) {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L135

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
145:        if (state_ != ProposalState.Succeeded) {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L145

292:        if (state_ != ProposalState.Succeeded) {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L292

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
69:        if (support != 1) {

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L69

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
73:        if (params.length != 64) {

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L73

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
80:        if (!isContender(proposalId, contender)) {

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L80

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
83:        if (isNominee(proposalId, contender)) {

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L83

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
90:        if (votes + prevVotesUsed > weight) {

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L90

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
98:        if (prevVotesReceived + votes >= votesThreshold) {

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L98

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
41:        if (!isSupportedDateTime) {

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L41

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
60:        if (startTimestamp <= block.timestamp) {

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L60

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
56:        if (_fullWeightDuration > _votingPeriod) {

Context:-

SecurityCouncilMemberElectionGovernor.sol#L56

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
68:        if (!Address.isContract(address(_nomineeElectionGovernor))) {

Context:-

SecurityCouncilMemberElectionGovernor.sol#L68

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
72:        if (!Address.isContract(address(_securityCouncilManager))) {

Context:-

SecurityCouncilMemberElectionGovernor.sol#L72

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
79:        if (msg.sender != address(nomineeElectionGovernor)) {

Context:-

SecurityCouncilMemberElectionGovernor.sol#L79

File:governance/src/UpgradeExecRouteBuilder.sol
72:        if (_l1ArbitrumTimelock == address(0)) {

Context:-

UpgradeExecRouteBuilder.sol#L72

File:governance/src/UpgradeExecRouteBuilder.sol
78:            if (chainAndUpExecLocation.location.upgradeExecutor == address(0)) {

Context:-

UpgradeExecRouteBuilder.sol#L78

File:governance/src/UpgradeExecRouteBuilder.sol
81:            if (upExecLocationExists(chainAndUpExecLocation.chainId)) {

Context:-

UpgradeExecRouteBuilder.sol#L81

File:governance/src/UpgradeExecRouteBuilder.sol
113:        if (chainIds.length != actionAddresses.length) {

Context:-

UpgradeExecRouteBuilder.sol#L113

File:governance/src/UpgradeExecRouteBuilder.sol
116:        if (chainIds.length != actionValues.length) {

Context:-

UpgradeExecRouteBuilder.sol#L116

File:governance/src/UpgradeExecRouteBuilder.sol
119:        if (chainIds.length != actionDatas.length) {

Context:-

UpgradeExecRouteBuilder.sol#L119

File:governance/src/UpgradeExecRouteBuilder.sol
131:            if (upExecLocation.upgradeExecutor == address(0)) {

Context:-

UpgradeExecRouteBuilder.sol#L131

File:governance/src/UpgradeExecRouteBuilder.sol
134:            if (actionDatas[i].length == 0) {

Context:-

UpgradeExecRouteBuilder.sol#L134

File:governance/src/UpgradeExecRouteBuilder.sol
143:            if (upExecLocation.inbox == address(0)) {

Context:-

UpgradeExecRouteBuilder.sol#L143

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
43:        if (_nonce <= updateNonce) {

Context:-

SecurityCouncilMemberSyncAction.sol#L43

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
62:            if (!securityCouncil.isOwner(member)) {

Context:-

SecurityCouncilMemberSyncAction.sol#L62

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
69:            if (!SecurityCouncilMgmtUtils.isInArray(owner, _updatedMembers)) {

Context:-

SecurityCouncilMemberSyncAction.sol#L69

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
107:            if (currentOwner == _owner) {

Context:-

SecurityCouncilMemberSyncAction.sol#L107

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
43:        if (

Context:-

SecurityCouncilMemberSyncAction.sol#L43

62:        if (

Context:-

SecurityCouncilMemberSyncAction.sol#L62

69:        if (

Context:-

SecurityCouncilMemberSyncAction.sol#L69

107:        if (

Context:-

SecurityCouncilMemberSyncAction.sol#L107

128:        if (

Context:-

SecurityCouncilMemberSyncAction.sol#L128

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
7:            if (arr[i] == addr) {

Context:-

SecurityCouncilMgmtUtils.sol#L7

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
24:            if (!excludeList[nominee]) {

Context:-

SecurityCouncilMgmtUtils.sol#L24

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
86:        if (!Address.isContract(dp.govChainEmergencySecurityCouncil)) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L86

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
90:        if (!Address.isContract(dp.govChainProxyAdmin)) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L90

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
94:        if (!Address.isContract(dp.l2UpgradeExecutor)) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L94

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
98:        if (!Address.isContract(dp.arbToken)) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L98

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
102:        if (dp.nomineeVetter == address(0)) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L102

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
107:        if (owners.length != (dp.firstCohort.length + dp.secondCohort.length)) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L107

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
112:            if (!govChainEmergencySCSafe.isOwner(dp.firstCohort[i])) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L112

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
118:            if (!govChainEmergencySCSafe.isOwner(dp.secondCohort[i])) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L118

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
57:        if (array1.length != array2.length) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L57

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
64:                if (array1[i] == array2[j]) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L64

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
69:            if (!found) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L69

82:            if (!found) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L82

NC-23 | Empty Function Body - Consider commenting why

Description :-

Proof Of Concept

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
52:function __SecurityCouncilNomineeElectionGovernorCounting_init() internal onlyInitializing {}

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L52

NC-24 | Reduce gas usage by moving to Solidity 0.8.19 or later

Description :-

See this link for the full details

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilManager.sol#L2

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L2

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L2

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L2

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilMemberElectionGovernor.sol#L2

File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol
2:pragma solidity 0.8.16;

Context:-

ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L2

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
3:pragma solidity 0.8.16;

Context:-

ElectionGovernor.sol#L3

File:governance/src/UpgradeExecRouteBuilder.sol
2:pragma solidity 0.8.16;

Context:-

UpgradeExecRouteBuilder.sol#L2

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilMemberSyncAction.sol#L2

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilMgmtUtils.sol#L2

File:governance/src/security-council-mgmt/Common.sol
2:pragma solidity 0.8.16;

Context:-

Common.sol#L2

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
2:pragma solidity 0.8.16;

Context:-

L2SecurityCouncilMgmtFactory.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
2:pragma solidity 0.8.16;

Context:-

GovernanceChainSCMgmtActivationAction.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
2:pragma solidity 0.8.16;

Context:-

L1SCMgmtActivationAction.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol
2:pragma solidity 0.8.16;

Context:-

NonGovernanceChainSCMgmtActivationAction.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
2:pragma solidity 0.8.16;

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L2

File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol
2:pragma solidity 0.8.16;

Context:-

KeyValueStore.sol#L2

File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol
2:pragma solidity 0.8.16;

Context:-

ActionExecutionRecord.sol#L2

NC-25 | Keccak Constant values should used to immutable rather than constant

Description :-

There is a difference between constant variables and immutable variables, and they should each be used in their appropriate contexts.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
79:    bytes32 public constant COHORT_REPLACER_ROLE = keccak256("COHORT_REPLACER");

Context:-

SecurityCouncilManager.sol#L79

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
80:    bytes32 public constant MEMBER_ADDER_ROLE = keccak256("MEMBER_ADDER");

Context:-

SecurityCouncilManager.sol#L80

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
81:    bytes32 public constant MEMBER_REPLACER_ROLE = keccak256("MEMBER_REPLACER");

Context:-

SecurityCouncilManager.sol#L81

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
82:    bytes32 public constant MEMBER_ROTATOR_ROLE = keccak256("MEMBER_ROTATOR");

Context:-

SecurityCouncilManager.sol#L82

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
83:    bytes32 public constant MEMBER_REMOVER_ROLE = keccak256("MEMBER_REMOVER");

Context:-

SecurityCouncilManager.sol#L83

NC-26 | Use block.number instead of block.timestamp

Description :-

Block timestamps have historically been used for a variety of applications, such as entropy for random numbers (see the Entropy Illusion for further details), locking funds for periods of time, and various state-changing conditional statements that are time-dependent. Miners have the ability to adjust timestamps slightly, which can prove to be dangerous if block timestamps are used incorrectly in smart contracts.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
167:        if (block.timestamp < thisElectionStartTs) {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L167

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
168:            revert CreateTooEarly(block.timestamp, thisElectionStartTs);

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L168

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
60:        if (startTimestamp <= block.timestamp) {

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L60

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
61:            revert StartDateTooEarly(startTimestamp, block.timestamp);

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L61

NC-27 | Use Ownable2StepUpgradeable instead of OwnableUpgradeable contract

Description :-

There is another Openzeppelin Ownable contract (Ownable2StepUpgradeable.sol) has transferOwnership function , use it is more secure due to 2-stage ownership transfer.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
5:import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L5

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
23:    OwnableUpgradeable,

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L23

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
6:import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

Context:-

SecurityCouncilMemberElectionGovernor.sol#L6

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
23:    OwnableUpgradeable,

Context:-

SecurityCouncilMemberElectionGovernor.sol#L23

NC-28 | Mark visibility of initialize(...) functions as external

Description :-

the initialize function will not be called from the contract and it doesn't require public visibility so the visibility should be changed to external

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
103:    function initialize(InitParams memory params) public initializer {
104:        __Governor_init("SecurityCouncilNomineeElectionGovernor");
105:        __GovernorVotes_init(params.token);
106:        __SecurityCouncilNomineeElectionGovernorCounting_init();
107:        __ArbitrumGovernorVotesQuorumFraction_init(params.quorumNumeratorValue);
108:        __GovernorSettings_init(0, params.votingPeriod, 0); // votingDelay and proposalThreshold are set to 0
109:        __SecurityCouncilNomineeElectionGovernorTiming_init(
110:            params.firstNominationStartDate, params.nomineeVettingDuration
111:        );
112:        _transferOwnership(params.owner);
113:
114:        nomineeVetter = params.nomineeVetter;
115:        if (!Address.isContract(address(params.securityCouncilManager))) {
116:            revert NotAContract(address(params.securityCouncilManager));
117:        }
118:        securityCouncilManager = params.securityCouncilManager;
119:        if (!Address.isContract(address(params.securityCouncilMemberElectionGovernor))) {
120:            revert NotAContract(address(params.securityCouncilMemberElectionGovernor));
121:        }
122:        securityCouncilMemberElectionGovernor = params.securityCouncilMemberElectionGovernor;
123:
124:        // elsewhere we make assumptions that the number of nominees
125:        // is not greater than 500
126:        // This value can still be updated via updateQuorumNumerator to a lower value
127:        // if it is deemed ok, however we put a quick check here as a reminder
128:        if ((quorumDenominator() / params.quorumNumeratorValue) > 500) {
129:            revert QuorumNumeratorTooLow(params.quorumNumeratorValue);
130:        }
131:    }

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L103-L131

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
48:    function initialize(
49:        ISecurityCouncilNomineeElectionGovernor _nomineeElectionGovernor,
50:        ISecurityCouncilManager _securityCouncilManager,
51:        IVotesUpgradeable _token,
52:        address _owner,
53:        uint256 _votingPeriod,
54:        uint256 _fullWeightDuration
55:    ) public initializer {
56:        if (_fullWeightDuration > _votingPeriod) {
57:            revert InvalidDurations(_fullWeightDuration, _votingPeriod);
58:        }
59:
60:        __Governor_init("SecurityCouncilMemberElectionGovernor");
61:        __GovernorVotes_init(_token);
62:        __SecurityCouncilMemberElectionGovernorCounting_init({
63:            initialFullWeightDuration: _fullWeightDuration
64:        });
65:        __GovernorSettings_init(0, _votingPeriod, 0);
66:        _transferOwnership(_owner);
67:
68:        if (!Address.isContract(address(_nomineeElectionGovernor))) {
69:            revert NotAContract(address(_nomineeElectionGovernor));
70:        }
71:        nomineeElectionGovernor = _nomineeElectionGovernor;
72:        if (!Address.isContract(address(_securityCouncilManager))) {
73:            revert NotAContract(address(_securityCouncilManager));
74:        }
75:        securityCouncilManager = _securityCouncilManager;
76:    }

Context:-

SecurityCouncilMemberElectionGovernor.sol#L48-L76

NC-29 | Unused State variables

Description :-

Consider removing unused State variables or moving it to a higher level contract.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
77:    address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;

Context:-

SecurityCouncilManager.sol#L77

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
184:    uint256[49] private __gap;

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L184

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
101:    uint256[45] private __gap;

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L101

File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol
54:    uint256[50] private __gap;

Context:-

ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L54

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
59:    uint256[50] private __gap;

Context:-

ElectionGovernor.sol#L59

NC-30 | Event is not properly indexed

Description :-

The emitted events are not indexed, making off-chain scripts such as front-ends of dApps difficult to filter the events efficiently.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
33:    event CohortReplaced(address[] newCohort, Cohort indexed cohort);

Context:-

SecurityCouncilManager.sol#L33

36:    event MemberReplaced(address indexed replacedMember, address indexed newMember, Cohort cohort);

Context:-

SecurityCouncilManager.sol#L36

37:    event MemberRotated(address indexed replacedAddress, address indexed newAddress, Cohort cohort);

Context:-

SecurityCouncilManager.sol#L37

38:    event SecurityCouncilAdded(
39:        address securityCouncil, address updateAction, uint256 securityCouncilsLength
40:    );

Context:-

SecurityCouncilManager.sol#L38-L40

41:    event SecurityCouncilRemoved(
42:        address securityCouncil, address updateAction, uint256 securityCouncilsLength
43:    );

Context:-

SecurityCouncilManager.sol#L41-L43

44:    event UpgradeExecRouteBuilderSet(address UpgradeExecRouteBuilder);

Context:-

SecurityCouncilManager.sol#L44

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
35:    event VoteCastForContender(
36:        uint256 indexed proposalId,
37:        address indexed voter,
38:        address indexed contender,
39:        uint256 votes,
40:        uint256 totalUsedVotes,
41:        uint256 usableVotes
42:    );

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L35-L42

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
14:    event UpdateNonceTooLow(
15:        address indexed securityCouncil, uint256 currrentNonce, uint256 providedNonce
16:    );

Context:-

SecurityCouncilMemberSyncAction.sol#L14-L16

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
56:    event ContractsDeployed(DeployedContracts deployedContracts);

Context:-

L2SecurityCouncilMgmtFactory.sol#L56

NC-31 | public functions not called by the contract should be declared external instead

Description :-

The following functions could be set external to save gas and improve code quality.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
368:    function isCompliantNominee(uint256 proposalId, address account) public view returns (bool) {
369:        return isNominee(proposalId, account) && !_elections[proposalId].isExcluded[account];
370:    }

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L368-L370

373:    function compliantNominees(uint256 proposalId) public view returns (address[] memory) {
374:        ElectionInfo storage election = _elections[proposalId];
375:        address[] memory maybeCompliantNominees =
376:            SecurityCouncilNomineeElectionGovernorCountingUpgradeable.nominees(proposalId);
377:        return SecurityCouncilMgmtUtils.filterAddressesWithExcludeList(
378:            maybeCompliantNominees, election.isExcluded
379:        );
380:    }

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L373-L380

388:    function currentCohort() public view returns (Cohort) {
389:        // current cohort is at electionCount - 1
390:        return electionCount == 0 ? Cohort.FIRST : electionIndexToCohort(electionCount - 1);
391:    }

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L388-L391

448:    function castVoteBySig(uint256, uint8, uint8, bytes32, bytes32)
449:        public
450:        virtual
451:        override
452:        returns (uint256)
453:    {
454:        revert CastVoteDisabled();
455:    }

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L448-L455

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
128:    function COUNTING_MODE() public pure virtual override returns (string memory) {
129:        return "support=for&params=account&counting=threshold";
130:    }

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L128-L130

133:    function hasVoted(uint256 proposalId, address account) public view override returns (bool) {
134:        return _elections[proposalId].votesUsed[account] > 0;
135:    }

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L133-L135

143:    function nomineeCount(uint256 proposalId) public view returns (uint256) {
144:        return _elections[proposalId].nominees.length;
145:    }

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L143-L145

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
69:    function proposalVettingDeadline(uint256 proposalId) public view returns (uint256) {
70:        return proposalDeadline(proposalId) + nomineeVettingDuration;
71:    }

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L69-L71

75:    function electionToTimestamp(uint256 electionIndex) public view returns (uint256) {
76:        // subtract one to make month 0 indexed
77:        uint256 month = firstNominationStartDate.month - 1;
78:
79:        month += 6 * electionIndex;
80:        uint256 year = firstNominationStartDate.year + month / 12;
81:        month = month % 12;
82:
83:        // add one to make month 1 indexed
84:        month += 1;
85:
86:        return DateTimeLib.dateTimeToTimestamp({
87:            year: year,
88:            month: month,
89:            day: firstNominationStartDate.day,
90:            hour: firstNominationStartDate.hour,
91:            minute: 0,
92:            second: 0
93:        });
94:    }

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L75-L94

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
138:    function proposalThreshold()
139:        public
140:        pure
141:        override(GovernorSettingsUpgradeable, GovernorUpgradeable)
142:        returns (uint256)
143:    {
144:        return 0;
145:    }

Context:-

SecurityCouncilMemberElectionGovernor.sol#L138-L145

148:    function quorum(uint256) public pure override returns (uint256) {
149:        return 0;
150:    }

Context:-

SecurityCouncilMemberElectionGovernor.sol#L148-L150

206:    function castVoteBySig(uint256, uint8, uint8, bytes32, bytes32)
207:        public
208:        virtual
209:        override
210:        returns (uint256)
211:    {
212:        revert CastVoteDisabled();
213:    }

Context:-

SecurityCouncilMemberElectionGovernor.sol#L206-L213

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
16:    function getProposeArgs(uint256 electionIndex)
17:        public
18:        pure
19:        returns (address[] memory, uint256[] memory, bytes[] memory, string memory)
20:    {
21:        // encode the election index for later use
22:        bytes[] memory electionData = new bytes[](1);
23:        electionData[0] = abi.encode(electionIndex);
24:        return (
25:            new address[](1),
26:            new uint256[](1),
27:            electionData,
28:            electionIndexToDescription(electionIndex)
29:        );
30:    }

Context:-

ElectionGovernor.sol#L16-L30

50:    function electionIndexToCohort(uint256 electionIndex) public pure returns (Cohort) {
51:        return Cohort(electionIndex % 2);
52:    }

Context:-

ElectionGovernor.sol#L50-L52

File:governance/src/UpgradeExecRouteBuilder.sol
186:    function createActionRouteDataWithDefaults(
187:        uint256[] memory chainIds,
188:        address[] memory actionAddresses,
189:        bytes32 timelockSalt
190:    ) public view returns (address, bytes memory) {
191:        uint256[] memory values = new uint256[](chainIds.length);
192:        bytes[] memory actionDatas = new bytes[](chainIds.length);
193:        for (uint256 i = 0; i < chainIds.length; i++) {
194:            actionDatas[i] = DEFAULT_GOV_ACTION_CALLDATA;
195:            values[i] = DEFAULT_VALUE;
196:        }
197:        return createActionRouteData(
198:            chainIds, actionAddresses, values, actionDatas, DEFAULT_PREDECESSOR, timelockSalt
199:        );
200:    }

Context:-

UpgradeExecRouteBuilder.sol#L186-L200

NC-32 | internal functions not called by the contract should be removed

Description :-

If the functions are required by an interface, the contract should inherit from that interface and use the override keyword

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
324:    function _execute(
325:        uint256 proposalId,
326:        address[] memory, /* targets */
327:        uint256[] memory, /* values */
328:        bytes[] memory callDatas,
329:        bytes32 /*descriptionHash*/
330:    ) internal virtual override {
331:        // we can only execute when the vetting deadline has passed
332:        uint256 vettingDeadline = proposalVettingDeadline(proposalId);
333:        if (block.number <= vettingDeadline) {
334:            revert ProposalInVettingPeriod(block.number, vettingDeadline);
335:        }
336:
337:        uint256 cnCount = compliantNomineeCount(proposalId);
338:        uint256 cohortSize = securityCouncilManager.cohortSize();
339:        if (cnCount < cohortSize) {
340:            revert InsufficientCompliantNomineeCount(cnCount, cohortSize);
341:        }
342:
343:        uint256 electionIndex = extractElectionIndex(callDatas);
344:        uint256 memberElectionProposalId =
345:            securityCouncilMemberElectionGovernor.proposeFromNomineeElectionGovernor(electionIndex);
346:
347:        // proposals in the member and nominee governors should have the same ids
348:        // so we do a safety check here to ensure this is the case
349:        if (memberElectionProposalId != proposalId) {
350:            revert ProposalIdMismatch(proposalId, memberElectionProposalId);
351:        }
352:    }

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L324-L352

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
52:    function __SecurityCouncilNomineeElectionGovernorCounting_init() internal onlyInitializing {}

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L52

62:    function _countVote(
63:        uint256 proposalId,
64:        address account,
65:        uint8 support,
66:        uint256 weight,
67:        bytes memory params
68:    ) internal virtual override {
69:        if (support != 1) {
70:            revert InvalidSupport(support);
71:        }
72:
73:        if (params.length != 64) {
74:            revert UnexpectedParamsLength(params.length);
75:        }
76:
77:        // params is encoded as (address contender, uint256 votes)
78:        (address contender, uint256 votes) = abi.decode(params, (address, uint256));
79:
80:        if (!isContender(proposalId, contender)) {
81:            revert NotEligibleContender(contender);
82:        }
83:        if (isNominee(proposalId, contender)) {
84:            revert NomineeAlreadyAdded(contender);
85:        }
86:
87:        NomineeElectionCountingInfo storage election = _elections[proposalId];
88:        uint256 prevVotesUsed = election.votesUsed[account];
89:
90:        if (votes + prevVotesUsed > weight) {
91:            revert InsufficientTokens(votes, prevVotesUsed, weight);
92:        }
93:
94:        uint256 prevVotesReceived = election.votesReceived[contender];
95:        uint256 votesThreshold = quorum(proposalSnapshot(proposalId));
96:
97:        uint256 actualVotes = votes;
98:        if (prevVotesReceived + votes >= votesThreshold) {
99:            // we pushed the contender over the line
100:            // we should only give the contender enough votes to get to the line so that we don't waste votes
101:            actualVotes = votesThreshold - prevVotesReceived;
102:
103:            // push the contender to the nominees
104:            _addNominee(proposalId, contender);
105:        }
106:
107:        election.votesUsed[account] = prevVotesUsed + actualVotes;
108:        election.votesReceived[contender] = prevVotesReceived + actualVotes;
109:
110:        emit VoteCastForContender({
111:            proposalId: proposalId,
112:            voter: account,
113:            contender: contender,
114:            votes: actualVotes,
115:            totalUsedVotes: prevVotesUsed + actualVotes,
116:            usableVotes: weight
117:        });
118:    }

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L62-L118

170:    function _quorumReached(uint256) internal pure override returns (bool) {
171:        return true;
172:    }

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L170-L172

175:    function _voteSucceeded(uint256) internal pure override returns (bool) {
176:        return true;
177:    }

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L175-L177

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
28:    function __SecurityCouncilNomineeElectionGovernorTiming_init(
29:        Date memory _firstNominationStartDate,
30:        uint256 _nomineeVettingDuration
31:    ) internal onlyInitializing {
32:        bool isSupportedDateTime = DateTimeLib.isSupportedDateTime({
33:            year: _firstNominationStartDate.year,
34:            month: _firstNominationStartDate.month,
35:            day: _firstNominationStartDate.day,
36:            hour: _firstNominationStartDate.hour,
37:            minute: 0,
38:            second: 0
39:        });
40:
41:        if (!isSupportedDateTime) {
42:            revert InvalidStartDate(
43:                _firstNominationStartDate.year,
44:                _firstNominationStartDate.month,
45:                _firstNominationStartDate.day,
46:                _firstNominationStartDate.hour
47:            );
48:        }
49:
50:        // make sure the start date is in the future
51:        uint256 startTimestamp = DateTimeLib.dateTimeToTimestamp({
52:            year: _firstNominationStartDate.year,
53:            month: _firstNominationStartDate.month,
54:            day: _firstNominationStartDate.day,
55:            hour: _firstNominationStartDate.hour,
56:            minute: 0,
57:            second: 0
58:        });
59:
60:        if (startTimestamp <= block.timestamp) {
61:            revert StartDateTooEarly(startTimestamp, block.timestamp);
62:        }
63:
64:        firstNominationStartDate = _firstNominationStartDate;
65:        nomineeVettingDuration = _nomineeVettingDuration;
66:    }

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L28-L66

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
115:    function _execute(
116:        uint256 proposalId,
117:        address[] memory, /* targets */
118:        uint256[] memory, /* values */
119:        bytes[] memory callDatas,
120:        bytes32 /* descriptionHash */
121:    ) internal override {
122:        // we know that the election index is part of the calldatas
123:        uint256 electionIndex = extractElectionIndex(callDatas);
124:
125:        // it's possible for this call to fail because of checks in the security council manager
126:        // getting into a state inconsistent with the elections, if it does the Security Council
127:        // will need to update the Manager so that this replaceCohort can go through
128:        // Otherwise this and future elections will remain blocked.
129:        securityCouncilManager.replaceCohort({
130:            _newCohort: topNominees(proposalId),
131:            _cohort: electionIndexToCohort(electionIndex)
132:        });
133:    }

Context:-

SecurityCouncilMemberElectionGovernor.sol#L115-L133

154:    function _isCompliantNominee(uint256 proposalId, address possibleNominee)
155:        internal
156:        view
157:        override
158:        returns (bool)
159:    {
160:        return nomineeElectionGovernor.isCompliantNominee(proposalId, possibleNominee);
161:    }

Context:-

SecurityCouncilMemberElectionGovernor.sol#L154-L161

164:    function _compliantNominees(uint256 proposalId)
165:        internal
166:        view
167:        override
168:        returns (address[] memory)
169:    {
170:        return nomineeElectionGovernor.compliantNominees(proposalId);
171:    }

Context:-

SecurityCouncilMemberElectionGovernor.sol#L164-L171

174:    function _targetMemberCount() internal view override returns (uint256) {
175:        return securityCouncilManager.cohortSize();
176:    }

Context:-

SecurityCouncilMemberElectionGovernor.sol#L174-L176

File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol
24:    function __ArbitrumGovernorVotesQuorumFraction_init(uint256 quorumNumeratorValue)
25:        internal
26:        onlyInitializing
27:    {
28:        __GovernorVotesQuorumFraction_init(quorumNumeratorValue);
29:    }

Context:-

ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L24-L29

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
34:    function extractElectionIndex(bytes[] memory callDatas) internal pure returns (uint256) {
35:        return abi.decode(callDatas[0], (uint256));
36:    }

Context:-

ElectionGovernor.sol#L34-L36

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
5:    function isInArray(address addr, address[] memory arr) internal pure returns (bool) {
6:        for (uint256 i = 0; i < arr.length; i++) {
7:            if (arr[i] == addr) {
8:                return true;
9:            }
10:        }
11:        return false;
12:    }

Context:-

SecurityCouncilMgmtUtils.sol#L5-L12

15:    function filterAddressesWithExcludeList(
16:        address[] memory input,
17:        mapping(address => bool) storage excludeList
18:    ) internal view returns (address[] memory) {
19:        address[] memory intermediate = new address[](input.length);
20:        uint256 intermediateLength = 0;
21:
22:        for (uint256 i = 0; i < input.length; i++) {
23:            address nominee = input[i];
24:            if (!excludeList[nominee]) {
25:                intermediate[intermediateLength] = nominee;
26:                intermediateLength++;
27:            }
28:        }
29:
30:        address[] memory output = new address[](intermediateLength);
31:        for (uint256 i = 0; i < intermediateLength; i++) {
32:            output[i] = intermediate[i];
33:        }
34:
35:        return output;
36:    }

Context:-

SecurityCouncilMgmtUtils.sol#L15-L36

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
8:    function replaceEmergencySecurityCouncil(
9:        IGnosisSafe _prevSecurityCouncil,
10:        IGnosisSafe _newSecurityCouncil,
11:        uint256 _threshold,
12:        IUpgradeExecutor _upgradeExecutor
13:    ) internal {
14:        requireSafesEquivalent(_prevSecurityCouncil, _newSecurityCouncil, _threshold);
15:        bytes32 EXECUTOR_ROLE = _upgradeExecutor.EXECUTOR_ROLE();
16:        require(
17:            _upgradeExecutor.hasRole(EXECUTOR_ROLE, address(_prevSecurityCouncil)),
18:            "SecurityCouncilMgmtUpgradeLib: prev council not executor"
19:        );
20:        require(
21:            !_upgradeExecutor.hasRole(EXECUTOR_ROLE, address(_newSecurityCouncil)),
22:            "SecurityCouncilMgmtUpgradeLib: new council already executor"
23:        );
24:
25:        _upgradeExecutor.revokeRole(EXECUTOR_ROLE, address(_prevSecurityCouncil));
26:        _upgradeExecutor.grantRole(EXECUTOR_ROLE, address(_newSecurityCouncil));
27:    }

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L8-L27

File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol
25:    function _set(uint256 key, uint256 value) internal {
26:        store.set(computeKey(key), value);
27:    }

Context:-

ActionExecutionRecord.sol#L25-L27

31:    function _get(uint256 key) internal view returns (uint256) {
32:        return store.get(computeKey(key));
33:    }

Context:-

ActionExecutionRecord.sol#L31-L33

G-1 | Cache array length outside of loop

Description :-

If not cached, the solidity compiler will always read the length of the array during each iteration. That is, if it is a storage array, this is an extra sload operation (100 additional extra gas for each iteration except for the first) and if it is a memory array, this is an extra mload operation (3 additional gas for each iteration except for the first).

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
106:for (uint256 i = 0; i < _roles.memberRemovers.length; i++) {

Context:-

SecurityCouncilManager.sol#L106

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
118:for (uint256 i = 0; i < _securityCouncils.length; i++) {

Context:-

SecurityCouncilManager.sol#L118

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
135:for (uint256 i = 0; i < _newCohort.length; i++) {

Context:-

SecurityCouncilManager.sol#L135

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
164:for (uint256 j = 0; j < cohort.length; j++) {

Context:-

SecurityCouncilManager.sol#L164

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
251:for (uint256 i = 0; i < securityCouncils.length; i++) {

Context:-

SecurityCouncilManager.sol#L251

284:for (uint256 i = 0; i < securityCouncils.length; i++) {

Context:-

SecurityCouncilManager.sol#L284

392:for (uint256 i = 0; i < securityCouncils.length; i++) {

Context:-

SecurityCouncilManager.sol#L392

File:governance/src/UpgradeExecRouteBuilder.sol
76:for (uint256 i = 0; i < _upgradeExecutors.length; i++) {

Context:-

UpgradeExecRouteBuilder.sol#L76

File:governance/src/UpgradeExecRouteBuilder.sol
129:for (uint256 i = 0; i < chainIds.length; i++) {

Context:-

UpgradeExecRouteBuilder.sol#L129

193:for (uint256 i = 0; i < chainIds.length; i++) {

Context:-

UpgradeExecRouteBuilder.sol#L193

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
60:for (uint256 i = 0; i < _updatedMembers.length; i++) {

Context:-

SecurityCouncilMemberSyncAction.sol#L60

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
67:for (uint256 i = 0; i < previousOwners.length; i++) {

Context:-

SecurityCouncilMemberSyncAction.sol#L67

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
105:for (uint256 i = 0; i < owners.length; i++) {

Context:-

SecurityCouncilMemberSyncAction.sol#L105

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
6:for (uint256 i = 0; i < arr.length; i++) {

Context:-

SecurityCouncilMgmtUtils.sol#L6

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
22:for (uint256 i = 0; i < input.length; i++) {

Context:-

SecurityCouncilMgmtUtils.sol#L22

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
111:for (uint256 i = 0; i < dp.firstCohort.length; i++) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L111

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
117:for (uint256 i = 0; i < dp.secondCohort.length; i++) {

Context:-

L2SecurityCouncilMgmtFactory.sol#L117

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
61:for (uint256 i = 0; i < array1.length; i++) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L61

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
63:for (uint256 j = 0; j < array2.length; j++) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L63

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
74:for (uint256 i = 0; i < array2.length; i++) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L74

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
76:for (uint256 j = 0; j < array1.length; j++) {

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L76

G-2 | Functions guaranteed to revert when called by normal users can be marked payable

Description :-

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.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
176:function addMember(address _newMember, Cohort _cohort) external onlyRole(MEMBER_ADDER_ROLE) {

Context:-

SecurityCouncilManager.sol#L176

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
183:function removeMember(address _member) external onlyRole(MEMBER_REMOVER_ROLE) {

Context:-

SecurityCouncilManager.sol#L183

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
246:function setNomineeVetter(address _nomineeVetter) external onlyGovernance {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L246

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
290:function includeNominee(uint256 proposalId, address account) external onlyNomineeVetter {

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L290

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
52:function __SecurityCouncilNomineeElectionGovernorCounting_init() internal onlyInitializing {}

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L52

G-3 | abi.encode() is less efficient than abi.encodepacked()

Description :-

See for more information: https://github.com/ConnorBlockchain/Solidity-Encode-Gas-Comparison

Proof Of Concept

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
23:abi.encode(

Context:-

ElectionGovernor.sol#L23

File:governance/src/UpgradeExecRouteBuilder.sol
151:abi.encode(

Context:-

UpgradeExecRouteBuilder.sol#L151

File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol
27:abi.encode(

Context:-

KeyValueStore.sol#L27

File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol
38:abi.encode(

Context:-

ActionExecutionRecord.sol#L38

G-4 | keccak256() EXPRESSIONS WHICH ARE FIXED, CAN BE PRECALCULATED AND ASSIGNED TO THE CONSTANT VARIABLES.

Description :-

Instead of calculating the keccak256() when the contract is made, pre calculate them before and only give the result to a constant

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
79:constant COHORT_REPLACER_ROLE = keccak256("COHORT_REPLACER");

Context:-

SecurityCouncilManager.sol#L79

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
80:constant MEMBER_ADDER_ROLE = keccak256("MEMBER_ADDER");

Context:-

SecurityCouncilManager.sol#L80

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
81:constant MEMBER_REPLACER_ROLE = keccak256("MEMBER_REPLACER");

Context:-

SecurityCouncilManager.sol#L81

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
82:constant MEMBER_ROTATOR_ROLE = keccak256("MEMBER_ROTATOR");

Context:-

SecurityCouncilManager.sol#L82

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
83:constant MEMBER_REMOVER_ROLE = keccak256("MEMBER_REMOVER");

Context:-

SecurityCouncilManager.sol#L83

G-5 | >= costs less gas than >

Description :-

The compiler uses opcodes GT and ISZERO for solidity code that uses >, but only requires LT for >=, which saves 3 gas

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
106: < _

Context:-

SecurityCouncilManager.sol#L106

118: < _

Context:-

SecurityCouncilManager.sol#L118

135: < _

Context:-

SecurityCouncilManager.sol#L135

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
128: > 5

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L128

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
151: > v

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L151

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
167: < t

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L167

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
321: > t

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L321

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
339: < c

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L339

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
396: < 2

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L396

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
90: > w

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L90

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
134: > 0

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L134

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
56: > _

Context:-

SecurityCouncilMemberElectionGovernor.sol#L56

File:governance/src/UpgradeExecRouteBuilder.sol
76: < _

Context:-

UpgradeExecRouteBuilder.sol#L76

File:governance/src/UpgradeExecRouteBuilder.sol
129: < c

Context:-

UpgradeExecRouteBuilder.sol#L129

193: < c

Context:-

UpgradeExecRouteBuilder.sol#L193

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
60: < _

Context:-

SecurityCouncilMemberSyncAction.sol#L60

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
67: < p

Context:-

SecurityCouncilMemberSyncAction.sol#L67

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
105: < o

Context:-

SecurityCouncilMemberSyncAction.sol#L105

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
6: < a

Context:-

SecurityCouncilMgmtUtils.sol#L6

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
22: < i

Context:-

SecurityCouncilMgmtUtils.sol#L22

31: < i

Context:-

SecurityCouncilMgmtUtils.sol#L31

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
111: < d

Context:-

L2SecurityCouncilMgmtFactory.sol#L111

117: < d

Context:-

L2SecurityCouncilMgmtFactory.sol#L117

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
61: < a

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L61

63: < a

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L63

74: < a

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L74

76: < a

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L76

G-6 | ++i costs less gas than i++, especially when it's used in for-loops (--i/i-- too)

Description :-

Saves 5 gas per loop

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
106:i++

Context:-

SecurityCouncilManager.sol#L106

118:i++

Context:-

SecurityCouncilManager.sol#L118

135:i++

Context:-

SecurityCouncilManager.sol#L135

162:i++

Context:-

SecurityCouncilManager.sol#L162

251:i++

Context:-

SecurityCouncilManager.sol#L251

284:i++

Context:-

SecurityCouncilManager.sol#L284

339:i++

Context:-

SecurityCouncilManager.sol#L339

342:i++

Context:-

SecurityCouncilManager.sol#L342

392:i++

Context:-

SecurityCouncilManager.sol#L392

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
180:electionCount++

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L180

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
280:election.excludedNomineeCount++

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L280

File:governance/src/UpgradeExecRouteBuilder.sol
76:i++

Context:-

UpgradeExecRouteBuilder.sol#L76

129:i++

Context:-

UpgradeExecRouteBuilder.sol#L129

193:i++

Context:-

UpgradeExecRouteBuilder.sol#L193

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
60:i++

Context:-

SecurityCouncilMemberSyncAction.sol#L60

67:i++

Context:-

SecurityCouncilMemberSyncAction.sol#L67

105:i++

Context:-

SecurityCouncilMemberSyncAction.sol#L105

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
6:i++

Context:-

SecurityCouncilMgmtUtils.sol#L6

22:i++

Context:-

SecurityCouncilMgmtUtils.sol#L22

31:i++

Context:-

SecurityCouncilMgmtUtils.sol#L31

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
111:i++

Context:-

L2SecurityCouncilMgmtFactory.sol#L111

117:i++

Context:-

L2SecurityCouncilMgmtFactory.sol#L117

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
61:i++

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L61

74:i++

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L74

G-7 | x += y/x -= y costs more gas than x = x + y/x = x - y for state variables

Description :-

Using the addition operator instead of plus-equals saves 113 gas

Proof Of Concept

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
79:+=

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L79

84:+=

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L84

G-8 | Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead

Description :-

When using elements that are smaller than 32 bytes, your contracts gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size. https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
433:uint8

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L433

438:uint8

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L438

448:uint8

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L448

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
50:uint8

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L50

65:uint8

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L65

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
191:uint8

Context:-

SecurityCouncilMemberElectionGovernor.sol#L191

196:uint8

Context:-

SecurityCouncilMemberElectionGovernor.sol#L196

206:uint8

Context:-

SecurityCouncilMemberElectionGovernor.sol#L206

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
119:uint16

Context:-

SecurityCouncilMemberSyncAction.sol#L119

123:uint16

Context:-

SecurityCouncilMemberSyncAction.sol#L123

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
34:uint64

Context:-

L2SecurityCouncilMgmtFactory.sol#L34

G-9 | Using private rather than public for constants, saves gas

Description :-

If needed, the values can be read from the verified contract source code, or if there are multiple values there can be a single getter function that returns a tuple of the values of all currently-public constants. Saves 3406-3606 gas in deployment gas due to the compiler not having to create non-payable getter functions for deployment calldata, not having to store the bytes of the value outside of where it's used, and not adding another entry to the method ID table

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
77:public constant RETRYABLE_TICKET_MAGIC =

Context:-

SecurityCouncilManager.sol#L77

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
79:public constant COHORT_REPLACER_ROLE =

Context:-

SecurityCouncilManager.sol#L79

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
80:public constant MEMBER_ADDER_ROLE =

Context:-

SecurityCouncilManager.sol#L80

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
81:public constant MEMBER_REPLACER_ROLE =

Context:-

SecurityCouncilManager.sol#L81

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
82:public constant MEMBER_ROTATOR_ROLE =

Context:-

SecurityCouncilManager.sol#L82

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
83:public constant MEMBER_REMOVER_ROLE =

Context:-

SecurityCouncilManager.sol#L83

File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol
22:public constant EXCLUDE_ADDRESS =

Context:-

ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L22

File:governance/src/UpgradeExecRouteBuilder.sol
47:public constant RETRYABLE_TICKET_MAGIC =

Context:-

UpgradeExecRouteBuilder.sol#L47

File:governance/src/UpgradeExecRouteBuilder.sol
50:public constant DEFAULT_GOV_ACTION_CALLDATA =

Context:-

UpgradeExecRouteBuilder.sol#L50

File:governance/src/UpgradeExecRouteBuilder.sol
52:public constant DEFAULT_VALUE =

Context:-

UpgradeExecRouteBuilder.sol#L52

File:governance/src/UpgradeExecRouteBuilder.sol
54:public constant DEFAULT_PREDECESSOR =

Context:-

UpgradeExecRouteBuilder.sol#L54

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
19:public constant SENTINEL_OWNERS =

Context:-

SecurityCouncilMemberSyncAction.sol#L19

G-10 | Don't initialize variables with default value

Description :-

If a variable is not initialized, it is assumed to have the default value. Explicitly initializing a variable with its default value costs unnecessary gas. For more info, see Mudit Gupta's Blog at point No need to initialize variables with default values .

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
106:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L106

118:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L118

135:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L135

162:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L162

251:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L251

284:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L284

339:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L339

342:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L342

392:uint256 i = 0;

Context:-

SecurityCouncilManager.sol#L392

File:governance/src/UpgradeExecRouteBuilder.sol
52:uint256 public constant DEFAULT_VALUE = 0;

Context:-

UpgradeExecRouteBuilder.sol#L52

File:governance/src/UpgradeExecRouteBuilder.sol
76:uint256 i = 0;

Context:-

UpgradeExecRouteBuilder.sol#L76

129:uint256 i = 0;

Context:-

UpgradeExecRouteBuilder.sol#L129

193:uint256 i = 0;

Context:-

UpgradeExecRouteBuilder.sol#L193

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
60:uint256 i = 0;

Context:-

SecurityCouncilMemberSyncAction.sol#L60

67:uint256 i = 0;

Context:-

SecurityCouncilMemberSyncAction.sol#L67

105:uint256 i = 0;

Context:-

SecurityCouncilMemberSyncAction.sol#L105

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
6:uint256 i = 0;

Context:-

SecurityCouncilMgmtUtils.sol#L6

22:uint256 i = 0;

Context:-

SecurityCouncilMgmtUtils.sol#L22

31:uint256 i = 0;

Context:-

SecurityCouncilMgmtUtils.sol#L31

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
111:uint256 i = 0;

Context:-

L2SecurityCouncilMgmtFactory.sol#L111

117:uint256 i = 0;

Context:-

L2SecurityCouncilMgmtFactory.sol#L117

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
61:uint256 i = 0;

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L61

74:uint256 i = 0;

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L74

G-11 | Inverting the condition of an if-else-statement wastes gas

Description :-

Flipping the true and false blocks instead saves 3 gas

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
133:== Cohort.FIRST ?

Context:-

SecurityCouncilManager.sol#L133

147:== Cohort.FIRST ?

Context:-

SecurityCouncilManager.sol#L147

365:== Cohort.FIRST ?

Context:-

SecurityCouncilManager.sol#L365

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
390:== 0 ?

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L390

G-12 | ++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

Description :-

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

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
106:i++

Context:-

SecurityCouncilManager.sol#L106

118:i++

Context:-

SecurityCouncilManager.sol#L118

135:i++

Context:-

SecurityCouncilManager.sol#L135

162:i++

Context:-

SecurityCouncilManager.sol#L162

251:i++

Context:-

SecurityCouncilManager.sol#L251

284:i++

Context:-

SecurityCouncilManager.sol#L284

339:i++

Context:-

SecurityCouncilManager.sol#L339

342:i++

Context:-

SecurityCouncilManager.sol#L342

392:i++

Context:-

SecurityCouncilManager.sol#L392

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
180:electionCount++

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L180

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
280:election.excludedNomineeCount++

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L280

File:governance/src/UpgradeExecRouteBuilder.sol
76:i++

Context:-

UpgradeExecRouteBuilder.sol#L76

129:i++

Context:-

UpgradeExecRouteBuilder.sol#L129

193:i++

Context:-

UpgradeExecRouteBuilder.sol#L193

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
60:i++

Context:-

SecurityCouncilMemberSyncAction.sol#L60

67:i++

Context:-

SecurityCouncilMemberSyncAction.sol#L67

105:i++

Context:-

SecurityCouncilMemberSyncAction.sol#L105

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
6:i++

Context:-

SecurityCouncilMgmtUtils.sol#L6

22:i++

Context:-

SecurityCouncilMgmtUtils.sol#L22

31:i++

Context:-

SecurityCouncilMgmtUtils.sol#L31

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
111:i++

Context:-

L2SecurityCouncilMgmtFactory.sol#L111

117:i++

Context:-

L2SecurityCouncilMgmtFactory.sol#L117

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
61:i++

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L61

74:i++

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L74

G-13 | Gas saving is achieved by removing the delete keyword (~60k)

Description :-

30k gas savings were made by removing the delete keyword. The reason for using the delete keyword here is to reset the struct values (set to default value) in every operation. However, the struct values do not need to be zero each time the function is run. Therefore, the delete key word is unnecessary. If it is removed, around 30k gas savings will be achieved.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
133: delete firstCohort : delete secondCohort;

Context:-

SecurityCouncilManager.sol#L133

G-14 | Use != 0 instead of > 0 for unsigned integer comparison

Description :-

It is cheaper to use != 0 than > 0 for uint256.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
134:> 0

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L134

G-15 | 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. Furthermore, Solidity's division operation also includes a division-by-0 prevention which is bypassed using shifting.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
128: / p

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L128

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
80: / 1

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L80

File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol
40: / q

Context:-

ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L40

G-16 | Constructors can be marked payable

Description :-

Payable functions cost less gas to execute, since the compiler does not have to add extra checks to ensure that a payment wasn't provided. A constructor can safely be marked as payable, since only the deployer would be able to pass funds, and the project itself would not pass any funds.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
85:constructor

Context:-

SecurityCouncilManager.sol#L85

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
98:constructor

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L98

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
38:constructor

Context:-

SecurityCouncilMemberElectionGovernor.sol#L38

File:governance/src/UpgradeExecRouteBuilder.sol
67:constructor

Context:-

UpgradeExecRouteBuilder.sol#L67

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
21:constructor

Context:-

SecurityCouncilMemberSyncAction.sol#L21

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
25:constructor

Context:-

GovernanceChainSCMgmtActivationAction.sol#L25

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
16:constructor

Context:-

L1SCMgmtActivationAction.sol#L16

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol
13:constructor

Context:-

NonGovernanceChainSCMgmtActivationAction.sol#L13

File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol
18:constructor

Context:-

ActionExecutionRecord.sol#L18

G-17 | Reduce gas usage by moving to Solidity 0.8.19 or later

Description :-

See this link for the full details

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
2:pragma solidity 

Context:-

SecurityCouncilManager.sol#L2

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
2:pragma solidity 

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L2

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
2:pragma solidity 

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L2

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
2:pragma solidity 

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L2

File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol
2:pragma solidity 

Context:-

SecurityCouncilMemberElectionGovernor.sol#L2

File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol
2:pragma solidity 

Context:-

ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L2

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
3:pragma solidity 

Context:-

ElectionGovernor.sol#L3

File:governance/src/UpgradeExecRouteBuilder.sol
2:pragma solidity 

Context:-

UpgradeExecRouteBuilder.sol#L2

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
2:pragma solidity 

Context:-

SecurityCouncilMemberSyncAction.sol#L2

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
2:pragma solidity 

Context:-

SecurityCouncilMgmtUtils.sol#L2

File:governance/src/security-council-mgmt/Common.sol
2:pragma solidity 

Context:-

Common.sol#L2

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
2:pragma solidity 

Context:-

L2SecurityCouncilMgmtFactory.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol
2:pragma solidity 

Context:-

GovernanceChainSCMgmtActivationAction.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol
2:pragma solidity 

Context:-

L1SCMgmtActivationAction.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol
2:pragma solidity 

Context:-

NonGovernanceChainSCMgmtActivationAction.sol#L2

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
2:pragma solidity 

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L2

File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol
2:pragma solidity 

Context:-

KeyValueStore.sol#L2

File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol
2:pragma solidity 

Context:-

ActionExecutionRecord.sol#L2

G-18 | Use assembly to hash instead of Solidity

Description :-

hash can be done by use of assembly instead of keccak256(abi.encodePacked()) see

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
375:keccak256(abi.encodePacked(_

Context:-

SecurityCouncilManager.sol#L375

G-19 | USE BYTES32 INSTEAD OF STRING

Description :-

Use bytes32 instead of string to save gas whenever possible. String is a dynamic data structure and therefore is more gas consuming then bytes32.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
128:(string memory)

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L128

File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol
43:(string memory)

Context:-

ElectionGovernor.sol#L43

G-20 | Compute known value off-chain

Description :-

If You know what data to hash, there is no need to consume more computational power to hash it using keccak256 , you’ll end up consuming 2x amount of gas.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
79:constant COHORT_REPLACER_ROLE = keccak256("COHORT_REPLACER");

Context:-

SecurityCouncilManager.sol#L79

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
80:constant MEMBER_ADDER_ROLE = keccak256("MEMBER_ADDER");

Context:-

SecurityCouncilManager.sol#L80

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
81:constant MEMBER_REPLACER_ROLE = keccak256("MEMBER_REPLACER");

Context:-

SecurityCouncilManager.sol#L81

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
82:constant MEMBER_ROTATOR_ROLE = keccak256("MEMBER_ROTATOR");

Context:-

SecurityCouncilManager.sol#L82

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
83:constant MEMBER_REMOVER_ROLE = keccak256("MEMBER_REMOVER");

Context:-

SecurityCouncilManager.sol#L83

G-21 | Part of the code can be pre calculated

Description :-

If You know what data to hash, there is no need to consume more computational power to hash it using keccak256 , you’ll end up consuming 2x amount of gas.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
79:keccak256("COHORT_REPLACER");

Context:-

SecurityCouncilManager.sol#L79

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
80:keccak256("MEMBER_ADDER");

Context:-

SecurityCouncilManager.sol#L80

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
81:keccak256("MEMBER_REPLACER");

Context:-

SecurityCouncilManager.sol#L81

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
82:keccak256("MEMBER_ROTATOR");

Context:-

SecurityCouncilManager.sol#L82

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
83:keccak256("MEMBER_REMOVER");

Context:-

SecurityCouncilManager.sol#L83

G-22 | Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct, where appropriate

Description :-

Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot.

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
55:mapping(

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L55

56:mapping(

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L56

74:mapping(

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L74

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol
19:mapping(

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L19

20:mapping(

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L20

22:mapping(

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L22

26:mapping(

Context:-

SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L26

File:governance/src/UpgradeExecRouteBuilder.sol
62:mapping(

Context:-

UpgradeExecRouteBuilder.sol#L62

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
17:mapping(

Context:-

SecurityCouncilMgmtUtils.sol#L17

File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol
7:mapping(

Context:-

KeyValueStore.sol#L7

G-23 | Ternary operation is cheaper than if-else statement

Description :-

There are instances where a ternary operation can be used instead of if-else statement. In these cases, using ternary operation will save modest amounts of gas.

Proof Of Concept

File:governance/src/UpgradeExecRouteBuilder.sol
147: else {

Context:-

UpgradeExecRouteBuilder.sol#L147

G-24 | Sort Solidity operations using short-circuit mode

Description :-

Short-circuiting is a solidity contract development model that uses OR/AND logic to sequence different cost operations. It puts low gas cost operations in the front and high gas cost operations in the back, so that if the front is low If the cost operation is feasible, you can skip (short-circuit) the subsequent high-cost Ethereum virtual machine operation.

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
222:if (_addressToRemove == address(0) || _addressToAdd == address(0)

Context:-

SecurityCouncilManager.sol#L222

G-25 | Unnecessary cast

Description :-

Proof Of Concept

File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol
27:uint256(keccak256(abi.encode(owner, key)

Context:-

KeyValueStore.sol#L27

File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol
38:uint256(keccak256(abi.encode(actionContractId, key)

Context:-

ActionExecutionRecord.sol#L38

G-26 | Calling .length in a for loop wastes gas

Description :-

Rather than calling .length for an array in a for loop declaration, it is far more gas efficient to cache this length before and use that instead. This will prevent the array length from being called every loop iteration

Proof Of Concept

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
106:for (uint256 i = 0; i < _roles.memberRemovers.length; i++)

Context:-

SecurityCouncilManager.sol#L106

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
118:for (uint256 i = 0; i < _securityCouncils.length; i++)

Context:-

SecurityCouncilManager.sol#L118

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
135:for (uint256 i = 0; i < _newCohort.length; i++)

Context:-

SecurityCouncilManager.sol#L135

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
164:for (uint256 j = 0; j < cohort.length; j++)

Context:-

SecurityCouncilManager.sol#L164

File:governance/src/security-council-mgmt/SecurityCouncilManager.sol
251:for (uint256 i = 0; i < securityCouncils.length; i++)

Context:-

SecurityCouncilManager.sol#L251

284:for (uint256 i = 0; i < securityCouncils.length; i++)

Context:-

SecurityCouncilManager.sol#L284

392:for (uint256 i = 0; i < securityCouncils.length; i++)

Context:-

SecurityCouncilManager.sol#L392

File:governance/src/UpgradeExecRouteBuilder.sol
76:for (uint256 i = 0; i < _upgradeExecutors.length; i++)

Context:-

UpgradeExecRouteBuilder.sol#L76

File:governance/src/UpgradeExecRouteBuilder.sol
129:for (uint256 i = 0; i < chainIds.length; i++)

Context:-

UpgradeExecRouteBuilder.sol#L129

193:for (uint256 i = 0; i < chainIds.length; i++)

Context:-

UpgradeExecRouteBuilder.sol#L193

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
60:for (uint256 i = 0; i < _updatedMembers.length; i++)

Context:-

SecurityCouncilMemberSyncAction.sol#L60

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
67:for (uint256 i = 0; i < previousOwners.length; i++)

Context:-

SecurityCouncilMemberSyncAction.sol#L67

File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol
105:for (uint256 i = 0; i < owners.length; i++)

Context:-

SecurityCouncilMemberSyncAction.sol#L105

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
6:for (uint256 i = 0; i < arr.length; i++)

Context:-

SecurityCouncilMgmtUtils.sol#L6

File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol
22:for (uint256 i = 0; i < input.length; i++)

Context:-

SecurityCouncilMgmtUtils.sol#L22

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
111:for (uint256 i = 0; i < dp.firstCohort.length; i++)

Context:-

L2SecurityCouncilMgmtFactory.sol#L111

File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol
117:for (uint256 i = 0; i < dp.secondCohort.length; i++)

Context:-

L2SecurityCouncilMgmtFactory.sol#L117

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
61:for (uint256 i = 0; i < array1.length; i++)

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L61

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
63:for (uint256 j = 0; j < array2.length; j++)

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L63

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
74:for (uint256 i = 0; i < array2.length; i++)

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L74

File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol
76:for (uint256 j = 0; j < array1.length; j++)

Context:-

SecurityCouncilMgmtUpgradeLib.sol#L76

G-27 | unchecked {} can be used on the division of two uints in order to save gas

Description :-

Proof Of Concept

File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol
128:        if ((quorumDenominator() / 

Context:-

SecurityCouncilNomineeElectionGovernor.sol#L128

File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol
80:        uint256 year = firstNominationStartDate.year + month / 

Context:-

SecurityCouncilNomineeElectionGovernorTiming.sol#L80

File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol
40:            / 

Context:-

ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L40

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment