| 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 |
Contracts have owners with privileged rights to perform admin tasks and need to be trusted to not perform malicious updates or drain funds.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol126: onlyRole(SecurityCouncilManager.sol#L126
195: onlyRole(SecurityCouncilManager.sol#L195
208: onlyRole(SecurityCouncilManager.sol#L208
273: onlyRole(SecurityCouncilManager.sol#L273
281: onlyRole(SecurityCouncilManager.sol#L281
310: onlyRole(SecurityCouncilManager.sol#L310
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol55:contract L2SecurityCouncilMgmtFactory is Ownable L2SecurityCouncilMgmtFactory.sol#L55
When deploying to Optimism, will not be accurate due to the use of block.number.
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol151: if (block.number > vettingDeadline) {SecurityCouncilNomineeElectionGovernor.sol#L151
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol152: revert ProposalNotInVettingPeriod(block.number, vettingDeadline);SecurityCouncilNomineeElectionGovernor.sol#L152
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol333: if (block.number <= vettingDeadline) {SecurityCouncilNomineeElectionGovernor.sol#L333
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol334: revert ProposalInVettingPeriod(block.number, vettingDeadline);SecurityCouncilNomineeElectionGovernor.sol#L334
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
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol89: function initialize(SecurityCouncilManager.sol#L89
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol103: function initialize(SecurityCouncilNomineeElectionGovernor.sol#L103
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol48: function initialize(SecurityCouncilMemberElectionGovernor.sol#L48
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.
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol80: uint256 year = firstNominationStartDate.year + month / 12;SecurityCouncilNomineeElectionGovernorTiming.sol#L80
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.
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol112: _transferOwnershipSecurityCouncilNomineeElectionGovernor.sol#L112
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol66: _transferOwnershipSecurityCouncilMemberElectionGovernor.sol#L66
While looping large collections, it's possible to run out of gas - causing a DOS condition
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol106:for (uint256 i = 0; i < _roles.memberRemovers.length; i++) {SecurityCouncilManager.sol#L106
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol118:for (uint256 i = 0; i < _securityCouncils.length; i++) {SecurityCouncilManager.sol#L118
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol135:for (uint256 i = 0; i < _newCohort.length; i++) {SecurityCouncilManager.sol#L135
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol164:for (uint256 j = 0; j < cohort.length; j++) {SecurityCouncilManager.sol#L164
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol251:for (uint256 i = 0; i < securityCouncils.length; i++) {SecurityCouncilManager.sol#L251
284:for (uint256 i = 0; i < securityCouncils.length; i++) {SecurityCouncilManager.sol#L284
392:for (uint256 i = 0; i < securityCouncils.length; i++) {SecurityCouncilManager.sol#L392
File:governance/src/UpgradeExecRouteBuilder.sol76:for (uint256 i = 0; i < _upgradeExecutors.length; i++) {UpgradeExecRouteBuilder.sol#L76
File:governance/src/UpgradeExecRouteBuilder.sol129:for (uint256 i = 0; i < chainIds.length; i++) {UpgradeExecRouteBuilder.sol#L129
193:for (uint256 i = 0; i < chainIds.length; i++) {UpgradeExecRouteBuilder.sol#L193
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol60:for (uint256 i = 0; i < _updatedMembers.length; i++) {SecurityCouncilMemberSyncAction.sol#L60
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol67:for (uint256 i = 0; i < previousOwners.length; i++) {SecurityCouncilMemberSyncAction.sol#L67
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol105:for (uint256 i = 0; i < owners.length; i++) {SecurityCouncilMemberSyncAction.sol#L105
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol6:for (uint256 i = 0; i < arr.length; i++) {SecurityCouncilMgmtUtils.sol#L6
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol22:for (uint256 i = 0; i < input.length; i++) {SecurityCouncilMgmtUtils.sol#L22
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol111:for (uint256 i = 0; i < dp.firstCohort.length; i++) {L2SecurityCouncilMgmtFactory.sol#L111
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol117:for (uint256 i = 0; i < dp.secondCohort.length; i++) {L2SecurityCouncilMgmtFactory.sol#L117
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol61:for (uint256 i = 0; i < array1.length; i++) {SecurityCouncilMgmtUpgradeLib.sol#L61
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol63:for (uint256 j = 0; j < array2.length; j++) {SecurityCouncilMgmtUpgradeLib.sol#L63
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol74:for (uint256 i = 0; i < array2.length; i++) {SecurityCouncilMgmtUpgradeLib.sol#L74
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol76:for (uint256 j = 0; j < array1.length; j++) {SecurityCouncilMgmtUpgradeLib.sol#L76
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.
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol55:contract L2SecurityCouncilMgmtFactory is Ownable {L2SecurityCouncilMgmtFactory.sol#L55
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol301:return true;SecurityCouncilManager.sol#L301
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol171:return true;SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L171
176:return true;SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L176
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol73:return true;SecurityCouncilMemberSyncAction.sol#L73
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol8:return true;SecurityCouncilMgmtUtils.sol#L8
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol87:return true;SecurityCouncilMgmtUpgradeLib.sol#L87
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.
File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol40: / quorumDenominator();ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L40
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol167:block.timestamp < SecurityCouncilNomineeElectionGovernor.sol#L167
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.
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol112:_transferOwnership(params.owner);SecurityCouncilNomineeElectionGovernor.sol#L112
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol66:_transferOwnership(_owner);SecurityCouncilMemberElectionGovernor.sol#L66
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol77: address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;SecurityCouncilManager.sol#L77
File:governance/src/UpgradeExecRouteBuilder.sol47: address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;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()
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
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol375:keccak256(abi.encodePacked(_members, nonce));SecurityCouncilManager.sol#L375
Missing checks for zero-addresses may lead to infunctional protocol, if the variable addresses are updated incorrectly
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol248: nomineeVetter = _nomineeVetter;SecurityCouncilNomineeElectionGovernor.sol#L248
L-13 | For loops in public or external functions should be avoided due to high gas costs and possible DOS
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol106: for (uint256 i = 0; i < _roles.memberRemovers.length; i++) {
107: _grantRole(MEMBER_REMOVER_ROLE, _roles.memberRemovers[i]);
108: }SecurityCouncilManager.sol#L106-L108
118: for (uint256 i = 0; i < _securityCouncils.length; i++) {
119: _addSecurityCouncil(_securityCouncils[i]);
120: }SecurityCouncilManager.sol#L118-L120
135: for (uint256 i = 0; i < _newCohort.length; i++) {
136: _addMemberToCohortArray(_newCohort[i], _cohort);
137: }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: }SecurityCouncilManager.sol#L284-L303
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol60: 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: }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: }SecurityCouncilMemberSyncAction.sol#L67-L72
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol111: 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: }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: }L2SecurityCouncilMgmtFactory.sol#L117-L121
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.
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol23: OwnableUpgradeable,SecurityCouncilNomineeElectionGovernor.sol#L23
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol23: OwnableUpgradeable,SecurityCouncilMemberElectionGovernor.sol#L23
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol89: 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: }SecurityCouncilManager.sol#L89-L121
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol103: 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: }SecurityCouncilNomineeElectionGovernor.sol#L103-L131
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol48: 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: }SecurityCouncilMemberElectionGovernor.sol#L48-L76
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol176:function addMember(address _newMember, Cohort _cohort) external onlyRole(MEMBER_ADDER_ROLE) {SecurityCouncilManager.sol#L176
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol183:function removeMember(address _member) external onlyRole(MEMBER_REMOVER_ROLE) {SecurityCouncilManager.sol#L183
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol246:function setNomineeVetter(address _nomineeVetter) external onlyGovernance {SecurityCouncilNomineeElectionGovernor.sol#L246
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol290:function includeNominee(uint256 proposalId, address account) external onlyNomineeVetter {SecurityCouncilNomineeElectionGovernor.sol#L290
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol52:function __SecurityCouncilNomineeElectionGovernorCounting_init() internal onlyInitializing {}SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L52
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol4:import "../ArbitrumTimelock.sol";File:governance/src/security-council-mgmt/SecurityCouncilManager.sol5:import "../UpgradeExecutor.sol";File:governance/src/security-council-mgmt/SecurityCouncilManager.sol6:import "../L1ArbitrumTimelock.sol";File:governance/src/security-council-mgmt/SecurityCouncilManager.sol7:import "./SecurityCouncilMgmtUtils.sol";File:governance/src/security-council-mgmt/SecurityCouncilManager.sol8:import "./interfaces/ISecurityCouncilManager.sol";File:governance/src/security-council-mgmt/SecurityCouncilManager.sol9:import "./SecurityCouncilMemberSyncAction.sol";File:governance/src/security-council-mgmt/SecurityCouncilManager.sol10:import "../UpgradeExecRouteBuilder.sol";SecurityCouncilManager.sol#L10
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol11:import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";SecurityCouncilManager.sol#L11
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol12:import "@openzeppelin/contracts/utils/Address.sol";SecurityCouncilManager.sol#L12
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol13:import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";SecurityCouncilManager.sol#L13
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol14:import "./Common.sol";SecurityCouncilManager.sol#L14
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol4:import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol";SecurityCouncilNomineeElectionGovernor.sol#L4
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol5:import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";SecurityCouncilNomineeElectionGovernor.sol#L5
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol6:import "../interfaces/ISecurityCouncilMemberElectionGovernor.sol";SecurityCouncilNomineeElectionGovernor.sol#L6
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol7:import "../interfaces/ISecurityCouncilNomineeElectionGovernor.sol";SecurityCouncilNomineeElectionGovernor.sol#L7
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol8:import "./modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol";SecurityCouncilNomineeElectionGovernor.sol#L8
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol9:import "./modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol";SecurityCouncilNomineeElectionGovernor.sol#L9
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol10:import "./modules/SecurityCouncilNomineeElectionGovernorTiming.sol";SecurityCouncilNomineeElectionGovernor.sol#L10
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol11:import "./modules/ElectionGovernor.sol";SecurityCouncilNomineeElectionGovernor.sol#L11
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol12:import "../SecurityCouncilMgmtUtils.sol";SecurityCouncilNomineeElectionGovernor.sol#L12
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol4:import "@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol";SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L4
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol4:import "../../interfaces/ISecurityCouncilManager.sol";SecurityCouncilNomineeElectionGovernorTiming.sol#L4
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol6:import "@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol";SecurityCouncilNomineeElectionGovernorTiming.sol#L6
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol7:import "solady/utils/DateTimeLib.sol";SecurityCouncilNomineeElectionGovernorTiming.sol#L7
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol8:import "../../Common.sol";SecurityCouncilNomineeElectionGovernorTiming.sol#L8
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol4:import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol";SecurityCouncilMemberElectionGovernor.sol#L4
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol5:import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol";SecurityCouncilMemberElectionGovernor.sol#L5
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol6:import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";SecurityCouncilMemberElectionGovernor.sol#L6
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol7:import "./modules/SecurityCouncilMemberElectionGovernorCountingUpgradeable.sol";SecurityCouncilMemberElectionGovernor.sol#L7
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol8:import "../interfaces/ISecurityCouncilMemberElectionGovernor.sol";SecurityCouncilMemberElectionGovernor.sol#L8
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol9:import "../interfaces/ISecurityCouncilNomineeElectionGovernor.sol";SecurityCouncilMemberElectionGovernor.sol#L9
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol10:import "../interfaces/ISecurityCouncilManager.sol";SecurityCouncilMemberElectionGovernor.sol#L10
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol11:import "./modules/ElectionGovernor.sol";SecurityCouncilMemberElectionGovernor.sol#L11
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol5:import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol6:import "../../Common.sol";File:governance/src/UpgradeExecRouteBuilder.sol4:import "@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";UpgradeExecRouteBuilder.sol#L4
File:governance/src/UpgradeExecRouteBuilder.sol5:import "./UpgradeExecutor.sol";UpgradeExecRouteBuilder.sol#L5
File:governance/src/UpgradeExecRouteBuilder.sol6:import "./L1ArbitrumTimelock.sol";UpgradeExecRouteBuilder.sol#L6
File:governance/src/UpgradeExecRouteBuilder.sol7:import "./security-council-mgmt/Common.sol";UpgradeExecRouteBuilder.sol#L7
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol4:import "./interfaces/IGnosisSafe.sol";SecurityCouncilMemberSyncAction.sol#L4
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol5:import "./SecurityCouncilMgmtUtils.sol";SecurityCouncilMemberSyncAction.sol#L5
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol6:import "../gov-action-contracts/execution-record/ActionExecutionRecord.sol";SecurityCouncilMemberSyncAction.sol#L6
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol4:import "@openzeppelin/contracts/access/Ownable.sol";L2SecurityCouncilMgmtFactory.sol#L4
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol5:import "@openzeppelin/contracts/utils/Address.sol";L2SecurityCouncilMgmtFactory.sol#L5
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol6:import "../governors/SecurityCouncilMemberElectionGovernor.sol";L2SecurityCouncilMgmtFactory.sol#L6
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol7:import "../governors/SecurityCouncilNomineeElectionGovernor.sol";L2SecurityCouncilMgmtFactory.sol#L7
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol8:import "../SecurityCouncilManager.sol";L2SecurityCouncilMgmtFactory.sol#L8
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol9:import "../governors/SecurityCouncilMemberRemovalGovernor.sol";L2SecurityCouncilMgmtFactory.sol#L9
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol10:import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";L2SecurityCouncilMgmtFactory.sol#L10
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol11:import "../interfaces/ISecurityCouncilManager.sol";L2SecurityCouncilMgmtFactory.sol#L11
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol12:import "../interfaces/IGnosisSafe.sol";L2SecurityCouncilMgmtFactory.sol#L12
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol13:import "../../ArbitrumTimelock.sol";L2SecurityCouncilMgmtFactory.sol#L13
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol14:import "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol";L2SecurityCouncilMgmtFactory.sol#L14
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol15:import "../../UpgradeExecRouteBuilder.sol";L2SecurityCouncilMgmtFactory.sol#L15
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol16:import "../Common.sol";L2SecurityCouncilMgmtFactory.sol#L16
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol4:import "../../../security-council-mgmt/interfaces/IGnosisSafe.sol";GovernanceChainSCMgmtActivationAction.sol#L4
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol5:import "../../address-registries/L2AddressRegistryInterfaces.sol";GovernanceChainSCMgmtActivationAction.sol#L5
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol6:import "./SecurityCouncilMgmtUpgradeLib.sol";GovernanceChainSCMgmtActivationAction.sol#L6
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol7:import "../../../interfaces/IArbitrumDAOConstitution.sol";GovernanceChainSCMgmtActivationAction.sol#L7
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol8:import "../../../interfaces/IUpgradeExecutor.sol";GovernanceChainSCMgmtActivationAction.sol#L8
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol9:import "../../../interfaces/ICoreTimelock.sol";GovernanceChainSCMgmtActivationAction.sol#L9
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol10:import "@openzeppelin/contracts/utils/Address.sol";GovernanceChainSCMgmtActivationAction.sol#L10
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol4:import "../../../security-council-mgmt/interfaces/IGnosisSafe.sol";L1SCMgmtActivationAction.sol#L4
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol5:import "../../../interfaces/IUpgradeExecutor.sol";L1SCMgmtActivationAction.sol#L5
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol6:import "../../../interfaces/ICoreTimelock.sol";L1SCMgmtActivationAction.sol#L6
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol7:import "./SecurityCouncilMgmtUpgradeLib.sol";L1SCMgmtActivationAction.sol#L7
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol4:import "../../../security-council-mgmt/interfaces/IGnosisSafe.sol";NonGovernanceChainSCMgmtActivationAction.sol#L4
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol5:import "./SecurityCouncilMgmtUpgradeLib.sol";NonGovernanceChainSCMgmtActivationAction.sol#L5
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol4:import "../../../security-council-mgmt/interfaces/IGnosisSafe.sol";SecurityCouncilMgmtUpgradeLib.sol#L4
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol5:import "../../../interfaces/IUpgradeExecutor.sol";SecurityCouncilMgmtUpgradeLib.sol#L5
File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol4:import "./KeyValueStore.sol";File:governance/src/security-council-mgmt/SecurityCouncilManager.sol2:pragma solidity 0.8.16;File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol2:pragma solidity 0.8.16;SecurityCouncilNomineeElectionGovernor.sol#L2
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol2:pragma solidity 0.8.16;SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L2
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol2:pragma solidity 0.8.16;SecurityCouncilNomineeElectionGovernorTiming.sol#L2
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol2:pragma solidity 0.8.16;SecurityCouncilMemberElectionGovernor.sol#L2
File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol2:pragma solidity 0.8.16;ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L2
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol3:pragma solidity 0.8.16;File:governance/src/UpgradeExecRouteBuilder.sol2:pragma solidity 0.8.16;UpgradeExecRouteBuilder.sol#L2
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol2:pragma solidity 0.8.16;SecurityCouncilMemberSyncAction.sol#L2
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol2:pragma solidity 0.8.16;SecurityCouncilMgmtUtils.sol#L2
File:governance/src/security-council-mgmt/Common.sol2:pragma solidity 0.8.16;File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol2:pragma solidity 0.8.16;L2SecurityCouncilMgmtFactory.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol2:pragma solidity 0.8.16;GovernanceChainSCMgmtActivationAction.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol2:pragma solidity 0.8.16;L1SCMgmtActivationAction.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol2:pragma solidity 0.8.16;NonGovernanceChainSCMgmtActivationAction.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol2:pragma solidity 0.8.16;SecurityCouncilMgmtUpgradeLib.sol#L2
File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol2:pragma solidity 0.8.16;File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol2:pragma solidity 0.8.16;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
File:governance/src/UpgradeExecRouteBuilder.sol150: schedValues[i] = 0;UpgradeExecRouteBuilder.sol#L150
Since version 0.8.4 for appending bytes, bytes.concat() can be used instead of abi.encodePacked(,)
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol375: return keccak256(abi.encodePacked(_members, nonce));SecurityCouncilManager.sol#L375
The default value for variables is zero, so initializing them to zero is superfluous.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol106:uint256 i = 0;SecurityCouncilManager.sol#L106
118:uint256 i = 0;SecurityCouncilManager.sol#L118
135:uint256 i = 0;SecurityCouncilManager.sol#L135
162:uint256 i = 0;SecurityCouncilManager.sol#L162
251:uint256 i = 0;SecurityCouncilManager.sol#L251
284:uint256 i = 0;SecurityCouncilManager.sol#L284
339:uint256 i = 0;SecurityCouncilManager.sol#L339
342:uint256 i = 0;SecurityCouncilManager.sol#L342
392:uint256 i = 0;SecurityCouncilManager.sol#L392
File:governance/src/UpgradeExecRouteBuilder.sol52:uint256 public constant DEFAULT_VALUE = 0;UpgradeExecRouteBuilder.sol#L52
File:governance/src/UpgradeExecRouteBuilder.sol76:uint256 i = 0;UpgradeExecRouteBuilder.sol#L76
129:uint256 i = 0;UpgradeExecRouteBuilder.sol#L129
193:uint256 i = 0;UpgradeExecRouteBuilder.sol#L193
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol60:uint256 i = 0;SecurityCouncilMemberSyncAction.sol#L60
67:uint256 i = 0;SecurityCouncilMemberSyncAction.sol#L67
105:uint256 i = 0;SecurityCouncilMemberSyncAction.sol#L105
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol6:uint256 i = 0;SecurityCouncilMgmtUtils.sol#L6
22:uint256 i = 0;SecurityCouncilMgmtUtils.sol#L22
31:uint256 i = 0;SecurityCouncilMgmtUtils.sol#L31
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol111:uint256 i = 0;L2SecurityCouncilMgmtFactory.sol#L111
117:uint256 i = 0;L2SecurityCouncilMgmtFactory.sol#L117
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol61:uint256 i = 0;SecurityCouncilMgmtUpgradeLib.sol#L61
74:uint256 i = 0;SecurityCouncilMgmtUpgradeLib.sol#L74
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol77: address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;SecurityCouncilManager.sol#L77
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol79: bytes32 public constant COHORT_REPLACER_ROLE = keccak256("COHORT_REPLACER");SecurityCouncilManager.sol#L79
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol80: bytes32 public constant MEMBER_ADDER_ROLE = keccak256("MEMBER_ADDER");SecurityCouncilManager.sol#L80
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol81: bytes32 public constant MEMBER_REPLACER_ROLE = keccak256("MEMBER_REPLACER");SecurityCouncilManager.sol#L81
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol82: bytes32 public constant MEMBER_ROTATOR_ROLE = keccak256("MEMBER_ROTATOR");SecurityCouncilManager.sol#L82
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol83: bytes32 public constant MEMBER_REMOVER_ROLE = keccak256("MEMBER_REMOVER");SecurityCouncilManager.sol#L83
File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol22: address public constant EXCLUDE_ADDRESS = address(0xA4b86);ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L22
File:governance/src/UpgradeExecRouteBuilder.sol47: address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;UpgradeExecRouteBuilder.sol#L47
File:governance/src/UpgradeExecRouteBuilder.sol52: uint256 public constant DEFAULT_VALUE = 0;UpgradeExecRouteBuilder.sol#L52
File:governance/src/UpgradeExecRouteBuilder.sol54: bytes32 public constant DEFAULT_PREDECESSOR = bytes32(0);UpgradeExecRouteBuilder.sol#L54
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol19: address public constant SENTINEL_OWNERS = address(0x1);SecurityCouncilMemberSyncAction.sol#L19
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol415: return (newMembers, to, data);SecurityCouncilManager.sol#L415
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol396: return (electionCount < 2) ? Cohort.SECOND : electionIndexToCohort(electionCount - 2);SecurityCouncilNomineeElectionGovernor.sol#L396
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol401: return _elections[proposalId].isExcluded[possibleExcluded];SecurityCouncilNomineeElectionGovernor.sol#L401
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol406: return _elections[proposalId].excludedNomineeCount;SecurityCouncilNomineeElectionGovernor.sol#L406
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol417: return _elections[proposalId].isContender[possibleContender];SecurityCouncilNomineeElectionGovernor.sol#L417
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol134: return _elections[proposalId].votesUsed[account] > 0;SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L134
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol139: return _elections[proposalId].isNominee[contender];SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L139
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol144: return _elections[proposalId].nominees.length;SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L144
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol149: return _elections[proposalId].nominees;SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L149
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol154: return _elections[proposalId].votesUsed[account];SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L154
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol159: return _elections[proposalId].votesReceived[contender];SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L159
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol24: return (File:governance/src/UpgradeExecRouteBuilder.sol174: return (UpgradeExecRouteBuilder.sol#L174
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol119: return _get(uint160(securityCouncil));SecurityCouncilMemberSyncAction.sol#L119
File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol17: return _get(msg.sender, key);File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol22: return _get(owner, key);Divisions which do not divide by -1 cannot overflow or overflow so such operations can be unchecked to save gas
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol80:uint256 year = firstNominationStartDate.year + month / 12;SecurityCouncilNomineeElectionGovernorTiming.sol#L80
According to the Solidity Style Guide, Non-external/public variable and function names should begin with an underscore
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol34:function extractElectionIndex(bytes[] memory callDatas) internal pure returns (uint256) {File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol5:function isInArray(address addr, address[] memory arr) internal pure returns (bool) {SecurityCouncilMgmtUtils.sol#L5
Variable does not follow Solidity naming best pratices
File:governance/src/UpgradeExecRouteBuilder.sol57: address public immutable l1TimelockAddr;UpgradeExecRouteBuilder.sol#L57
File:governance/src/UpgradeExecRouteBuilder.sol60: uint256 public immutable l1TimelockMinDelay;UpgradeExecRouteBuilder.sol#L60
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol13: IGnosisSafe public immutable newEmergencySecurityCouncil;GovernanceChainSCMgmtActivationAction.sol#L13
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol14: IGnosisSafe public immutable newNonEmergencySecurityCouncil;GovernanceChainSCMgmtActivationAction.sol#L14
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol16: IGnosisSafe public immutable prevEmergencySecurityCouncil;GovernanceChainSCMgmtActivationAction.sol#L16
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol17: IGnosisSafe public immutable prevNonEmergencySecurityCouncil;GovernanceChainSCMgmtActivationAction.sol#L17
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol19: uint256 public immutable emergencySecurityCouncilThreshold;GovernanceChainSCMgmtActivationAction.sol#L19
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol20: uint256 public immutable nonEmergencySecurityCouncilThreshold;GovernanceChainSCMgmtActivationAction.sol#L20
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol22: address public immutable securityCouncilManager;GovernanceChainSCMgmtActivationAction.sol#L22
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol23: IL2AddressRegistry public immutable l2AddressRegistry;GovernanceChainSCMgmtActivationAction.sol#L23
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol10: IGnosisSafe public immutable newEmergencySecurityCouncil;L1SCMgmtActivationAction.sol#L10
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol11: IGnosisSafe public immutable prevEmergencySecurityCouncil;L1SCMgmtActivationAction.sol#L11
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol12: uint256 public immutable emergencySecurityCouncilThreshold;L1SCMgmtActivationAction.sol#L12
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol13: IUpgradeExecutor public immutable l1UpgradeExecutor;L1SCMgmtActivationAction.sol#L13
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol14: ICoreTimelock public immutable l1Timelock;L1SCMgmtActivationAction.sol#L14
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol8: IGnosisSafe public immutable newEmergencySecurityCouncil;NonGovernanceChainSCMgmtActivationAction.sol#L8
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol9: IGnosisSafe public immutable prevEmergencySecurityCouncil;NonGovernanceChainSCMgmtActivationAction.sol#L9
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol10: uint256 public immutable emergencySecurityCouncilThreshold;NonGovernanceChainSCMgmtActivationAction.sol#L10
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol11: IUpgradeExecutor public immutable upgradeExecutor;NonGovernanceChainSCMgmtActivationAction.sol#L11
File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol13: KeyValueStore public immutable store;File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol16: bytes32 public immutable actionContractId;block.timestamp is not an ideal proxy for time because of issues with synchronization, miner manipulation and changing block times.
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol167: if (block.timestamp < thisElectionStartTs) {SecurityCouncilNomineeElectionGovernor.sol#L167
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol168: revert CreateTooEarly(block.timestamp, thisElectionStartTs);SecurityCouncilNomineeElectionGovernor.sol#L168
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol60: if (startTimestamp <= block.timestamp) {SecurityCouncilNomineeElectionGovernorTiming.sol#L60
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol61: revert StartDateTooEarly(startTimestamp, block.timestamp);SecurityCouncilNomineeElectionGovernorTiming.sol#L61
Consider renaming to camelCase
File:governance/src/UpgradeExecRouteBuilder.sol9:interface DefaultGovAction {UpgradeExecRouteBuilder.sol#L9
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.
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol26:mapping(uint256 => NomineeElectionCountingInfo) private _elections;SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L26
File:governance/src/UpgradeExecRouteBuilder.sol62:mapping(uint256 => UpExecLocation) public upExecLocations;UpgradeExecRouteBuilder.sol#L62
File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol7:mapping(uint256 => uint256) public store;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.
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol55:contract L2SecurityCouncilMgmtFactory is Ownable L2SecurityCouncilMgmtFactory.sol#L55
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol77: address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;SecurityCouncilManager.sol#L77
File:governance/src/UpgradeExecRouteBuilder.sol47: address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;UpgradeExecRouteBuilder.sol#L47
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
File:governance/src/UpgradeExecRouteBuilder.sol9:interface DefaultGovAction {UpgradeExecRouteBuilder.sol#L9
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
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol133:delete firstCohort : delete secondCohort;SecurityCouncilManager.sol#L133
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol106:for (uint256 i = 0; i < _roles.memberRemovers.length; i++)SecurityCouncilManager.sol#L106
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol118:for (uint256 i = 0; i < _securityCouncils.length; i++)SecurityCouncilManager.sol#L118
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol135:for (uint256 i = 0; i < _newCohort.length; i++)SecurityCouncilManager.sol#L135
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol164:for (uint256 j = 0; j < cohort.length; j++)SecurityCouncilManager.sol#L164
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol251:for (uint256 i = 0; i < securityCouncils.length; i++)SecurityCouncilManager.sol#L251
284:for (uint256 i = 0; i < securityCouncils.length; i++)SecurityCouncilManager.sol#L284
392:for (uint256 i = 0; i < securityCouncils.length; i++)SecurityCouncilManager.sol#L392
File:governance/src/UpgradeExecRouteBuilder.sol76:for (uint256 i = 0; i < _upgradeExecutors.length; i++)UpgradeExecRouteBuilder.sol#L76
File:governance/src/UpgradeExecRouteBuilder.sol129:for (uint256 i = 0; i < chainIds.length; i++)UpgradeExecRouteBuilder.sol#L129
193:for (uint256 i = 0; i < chainIds.length; i++)UpgradeExecRouteBuilder.sol#L193
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol60:for (uint256 i = 0; i < _updatedMembers.length; i++)SecurityCouncilMemberSyncAction.sol#L60
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol67:for (uint256 i = 0; i < previousOwners.length; i++)SecurityCouncilMemberSyncAction.sol#L67
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol105:for (uint256 i = 0; i < owners.length; i++)SecurityCouncilMemberSyncAction.sol#L105
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol6:for (uint256 i = 0; i < arr.length; i++)SecurityCouncilMgmtUtils.sol#L6
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol22:for (uint256 i = 0; i < input.length; i++)SecurityCouncilMgmtUtils.sol#L22
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol111:for (uint256 i = 0; i < dp.firstCohort.length; i++)L2SecurityCouncilMgmtFactory.sol#L111
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol117:for (uint256 i = 0; i < dp.secondCohort.length; i++)L2SecurityCouncilMgmtFactory.sol#L117
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol61:for (uint256 i = 0; i < array1.length; i++)SecurityCouncilMgmtUpgradeLib.sol#L61
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol63:for (uint256 j = 0; j < array2.length; j++)SecurityCouncilMgmtUpgradeLib.sol#L63
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol74:for (uint256 i = 0; i < array2.length; i++)SecurityCouncilMgmtUpgradeLib.sol#L74
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol76:for (uint256 j = 0; j < array1.length; j++)SecurityCouncilMgmtUpgradeLib.sol#L76
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol144: ProposalState state_ SecurityCouncilNomineeElectionGovernor.sol#L144
225: ProposalState state_ SecurityCouncilNomineeElectionGovernor.sol#L225
291: ProposalState state_ SecurityCouncilNomineeElectionGovernor.sol#L291
abi.encodeCall() has compiler type safety, whereas the other two functions do not
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol396:abi.encodeWithSelector(SecurityCouncilManager.sol#L396
File:governance/src/UpgradeExecRouteBuilder.sol51:abi.encodeWithSelector(DefaultGovAction.perform.selector);UpgradeExecRouteBuilder.sol#L51
File:governance/src/UpgradeExecRouteBuilder.sol51:abi.encodeWithSelector(UpgradeExecRouteBuilder.sol#L51
138:abi.encodeWithSelector(UpgradeExecRouteBuilder.sol#L138
163:abi.encodeWithSelector(UpgradeExecRouteBuilder.sol#L163
176:abi.encodeWithSelector(UpgradeExecRouteBuilder.sol#L176
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol81:abi.encodeWithSelector(IGnosisSafe.addOwnerWithThreshold.selector, _member, _threshold)SecurityCouncilMemberSyncAction.sol#L81
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol81:abi.encodeWithSelector(SecurityCouncilMemberSyncAction.sol#L81
91:abi.encodeWithSelector(SecurityCouncilMemberSyncAction.sol#L91
See the control structures section of the Solidity Style Guide
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol97: if (_firstCohort.length != _secondCohort.length) {SecurityCouncilManager.sol#L97
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol112: if (!Address.isContract(_l2CoreGovTimelock)) {SecurityCouncilManager.sol#L112
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol128: if (_newCohort.length != cohortSize) {SecurityCouncilManager.sol#L128
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol144: if (_newMember == address(0)) {SecurityCouncilManager.sol#L144
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol148: if (cohort.length == cohortSize) {SecurityCouncilManager.sol#L148
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol151: if (firstCohortIncludes(_newMember)) {SecurityCouncilManager.sol#L151
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol154: if (secondCohortIncludes(_newMember)) {SecurityCouncilManager.sol#L154
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol165: if (_member == cohort[j]) {SecurityCouncilManager.sol#L165
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol184: if (_member == address(0)) {SecurityCouncilManager.sol#L184
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol222: if (_addressToRemove == address(0) || _addressToAdd == address(0)) {SecurityCouncilManager.sol#L222
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol232: if (securityCouncils.length == MAX_SECURITY_COUNCILS) {SecurityCouncilManager.sol#L232
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol97: if (SecurityCouncilManager.sol#L97
112: if (SecurityCouncilManager.sol#L112
128: if (SecurityCouncilManager.sol#L128
144: if (SecurityCouncilManager.sol#L144
148: if (SecurityCouncilManager.sol#L148
151: if (SecurityCouncilManager.sol#L151
154: if (SecurityCouncilManager.sol#L154
165: if (SecurityCouncilManager.sol#L165
184: if (SecurityCouncilManager.sol#L184
222: if (SecurityCouncilManager.sol#L222
232: if (SecurityCouncilManager.sol#L232
236: if (SecurityCouncilManager.sol#L236
243: if (SecurityCouncilManager.sol#L243
247: if (SecurityCouncilManager.sol#L247
254: if (SecurityCouncilManager.sol#L254
286: if (SecurityCouncilManager.sol#L286
318: if (SecurityCouncilManager.sol#L318
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol115: if (!Address.isContract(address(params.securityCouncilManager))) {SecurityCouncilNomineeElectionGovernor.sol#L115
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol119: if (!Address.isContract(address(params.securityCouncilMemberElectionGovernor))) {SecurityCouncilNomineeElectionGovernor.sol#L119
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol128: if ((quorumDenominator() / params.quorumNumeratorValue) > 500) {SecurityCouncilNomineeElectionGovernor.sol#L128
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol135: if (msg.sender != nomineeVetter) {SecurityCouncilNomineeElectionGovernor.sol#L135
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol145: if (state_ != ProposalState.Succeeded) {SecurityCouncilNomineeElectionGovernor.sol#L145
292: if (state_ != ProposalState.Succeeded) {SecurityCouncilNomineeElectionGovernor.sol#L292
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol69: if (support != 1) {SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L69
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol73: if (params.length != 64) {SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L73
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol80: if (!isContender(proposalId, contender)) {SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L80
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol83: if (isNominee(proposalId, contender)) {SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L83
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol90: if (votes + prevVotesUsed > weight) {SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L90
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol98: if (prevVotesReceived + votes >= votesThreshold) {SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L98
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol41: if (!isSupportedDateTime) {SecurityCouncilNomineeElectionGovernorTiming.sol#L41
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol60: if (startTimestamp <= block.timestamp) {SecurityCouncilNomineeElectionGovernorTiming.sol#L60
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol56: if (_fullWeightDuration > _votingPeriod) {SecurityCouncilMemberElectionGovernor.sol#L56
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol68: if (!Address.isContract(address(_nomineeElectionGovernor))) {SecurityCouncilMemberElectionGovernor.sol#L68
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol72: if (!Address.isContract(address(_securityCouncilManager))) {SecurityCouncilMemberElectionGovernor.sol#L72
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol79: if (msg.sender != address(nomineeElectionGovernor)) {SecurityCouncilMemberElectionGovernor.sol#L79
File:governance/src/UpgradeExecRouteBuilder.sol72: if (_l1ArbitrumTimelock == address(0)) {UpgradeExecRouteBuilder.sol#L72
File:governance/src/UpgradeExecRouteBuilder.sol78: if (chainAndUpExecLocation.location.upgradeExecutor == address(0)) {UpgradeExecRouteBuilder.sol#L78
File:governance/src/UpgradeExecRouteBuilder.sol81: if (upExecLocationExists(chainAndUpExecLocation.chainId)) {UpgradeExecRouteBuilder.sol#L81
File:governance/src/UpgradeExecRouteBuilder.sol113: if (chainIds.length != actionAddresses.length) {UpgradeExecRouteBuilder.sol#L113
File:governance/src/UpgradeExecRouteBuilder.sol116: if (chainIds.length != actionValues.length) {UpgradeExecRouteBuilder.sol#L116
File:governance/src/UpgradeExecRouteBuilder.sol119: if (chainIds.length != actionDatas.length) {UpgradeExecRouteBuilder.sol#L119
File:governance/src/UpgradeExecRouteBuilder.sol131: if (upExecLocation.upgradeExecutor == address(0)) {UpgradeExecRouteBuilder.sol#L131
File:governance/src/UpgradeExecRouteBuilder.sol134: if (actionDatas[i].length == 0) {UpgradeExecRouteBuilder.sol#L134
File:governance/src/UpgradeExecRouteBuilder.sol143: if (upExecLocation.inbox == address(0)) {UpgradeExecRouteBuilder.sol#L143
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol43: if (_nonce <= updateNonce) {SecurityCouncilMemberSyncAction.sol#L43
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol62: if (!securityCouncil.isOwner(member)) {SecurityCouncilMemberSyncAction.sol#L62
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol69: if (!SecurityCouncilMgmtUtils.isInArray(owner, _updatedMembers)) {SecurityCouncilMemberSyncAction.sol#L69
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol107: if (currentOwner == _owner) {SecurityCouncilMemberSyncAction.sol#L107
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol43: if (SecurityCouncilMemberSyncAction.sol#L43
62: if (SecurityCouncilMemberSyncAction.sol#L62
69: if (SecurityCouncilMemberSyncAction.sol#L69
107: if (SecurityCouncilMemberSyncAction.sol#L107
128: if (SecurityCouncilMemberSyncAction.sol#L128
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol7: if (arr[i] == addr) {SecurityCouncilMgmtUtils.sol#L7
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol24: if (!excludeList[nominee]) {SecurityCouncilMgmtUtils.sol#L24
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol86: if (!Address.isContract(dp.govChainEmergencySecurityCouncil)) {L2SecurityCouncilMgmtFactory.sol#L86
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol90: if (!Address.isContract(dp.govChainProxyAdmin)) {L2SecurityCouncilMgmtFactory.sol#L90
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol94: if (!Address.isContract(dp.l2UpgradeExecutor)) {L2SecurityCouncilMgmtFactory.sol#L94
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol98: if (!Address.isContract(dp.arbToken)) {L2SecurityCouncilMgmtFactory.sol#L98
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol102: if (dp.nomineeVetter == address(0)) {L2SecurityCouncilMgmtFactory.sol#L102
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol107: if (owners.length != (dp.firstCohort.length + dp.secondCohort.length)) {L2SecurityCouncilMgmtFactory.sol#L107
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol112: if (!govChainEmergencySCSafe.isOwner(dp.firstCohort[i])) {L2SecurityCouncilMgmtFactory.sol#L112
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol118: if (!govChainEmergencySCSafe.isOwner(dp.secondCohort[i])) {L2SecurityCouncilMgmtFactory.sol#L118
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol57: if (array1.length != array2.length) {SecurityCouncilMgmtUpgradeLib.sol#L57
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol64: if (array1[i] == array2[j]) {SecurityCouncilMgmtUpgradeLib.sol#L64
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol69: if (!found) {SecurityCouncilMgmtUpgradeLib.sol#L69
82: if (!found) {SecurityCouncilMgmtUpgradeLib.sol#L82
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol52:function __SecurityCouncilNomineeElectionGovernorCounting_init() internal onlyInitializing {}SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L52
See this link for the full details
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol2:pragma solidity 0.8.16;File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol2:pragma solidity 0.8.16;SecurityCouncilNomineeElectionGovernor.sol#L2
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol2:pragma solidity 0.8.16;SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L2
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol2:pragma solidity 0.8.16;SecurityCouncilNomineeElectionGovernorTiming.sol#L2
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol2:pragma solidity 0.8.16;SecurityCouncilMemberElectionGovernor.sol#L2
File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol2:pragma solidity 0.8.16;ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L2
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol3:pragma solidity 0.8.16;File:governance/src/UpgradeExecRouteBuilder.sol2:pragma solidity 0.8.16;UpgradeExecRouteBuilder.sol#L2
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol2:pragma solidity 0.8.16;SecurityCouncilMemberSyncAction.sol#L2
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol2:pragma solidity 0.8.16;SecurityCouncilMgmtUtils.sol#L2
File:governance/src/security-council-mgmt/Common.sol2:pragma solidity 0.8.16;File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol2:pragma solidity 0.8.16;L2SecurityCouncilMgmtFactory.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol2:pragma solidity 0.8.16;GovernanceChainSCMgmtActivationAction.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol2:pragma solidity 0.8.16;L1SCMgmtActivationAction.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol2:pragma solidity 0.8.16;NonGovernanceChainSCMgmtActivationAction.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol2:pragma solidity 0.8.16;SecurityCouncilMgmtUpgradeLib.sol#L2
File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol2:pragma solidity 0.8.16;File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol2:pragma solidity 0.8.16;There is a difference between constant variables and immutable variables, and they should each be used in their appropriate contexts.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol79: bytes32 public constant COHORT_REPLACER_ROLE = keccak256("COHORT_REPLACER");SecurityCouncilManager.sol#L79
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol80: bytes32 public constant MEMBER_ADDER_ROLE = keccak256("MEMBER_ADDER");SecurityCouncilManager.sol#L80
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol81: bytes32 public constant MEMBER_REPLACER_ROLE = keccak256("MEMBER_REPLACER");SecurityCouncilManager.sol#L81
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol82: bytes32 public constant MEMBER_ROTATOR_ROLE = keccak256("MEMBER_ROTATOR");SecurityCouncilManager.sol#L82
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol83: bytes32 public constant MEMBER_REMOVER_ROLE = keccak256("MEMBER_REMOVER");SecurityCouncilManager.sol#L83
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.
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol167: if (block.timestamp < thisElectionStartTs) {SecurityCouncilNomineeElectionGovernor.sol#L167
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol168: revert CreateTooEarly(block.timestamp, thisElectionStartTs);SecurityCouncilNomineeElectionGovernor.sol#L168
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol60: if (startTimestamp <= block.timestamp) {SecurityCouncilNomineeElectionGovernorTiming.sol#L60
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol61: revert StartDateTooEarly(startTimestamp, block.timestamp);SecurityCouncilNomineeElectionGovernorTiming.sol#L61
There is another Openzeppelin Ownable contract (Ownable2StepUpgradeable.sol) has transferOwnership function , use it is more secure due to 2-stage ownership transfer.
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol5:import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";SecurityCouncilNomineeElectionGovernor.sol#L5
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol23: OwnableUpgradeable,SecurityCouncilNomineeElectionGovernor.sol#L23
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol6:import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";SecurityCouncilMemberElectionGovernor.sol#L6
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol23: OwnableUpgradeable,SecurityCouncilMemberElectionGovernor.sol#L23
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
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol103: 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: }SecurityCouncilNomineeElectionGovernor.sol#L103-L131
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol48: 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: }SecurityCouncilMemberElectionGovernor.sol#L48-L76
Consider removing unused State variables or moving it to a higher level contract.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol77: address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C;SecurityCouncilManager.sol#L77
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol184: uint256[49] private __gap;SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L184
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol101: uint256[45] private __gap;SecurityCouncilNomineeElectionGovernorTiming.sol#L101
File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol54: uint256[50] private __gap;ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L54
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol59: uint256[50] private __gap;The emitted events are not indexed, making off-chain scripts such as front-ends of dApps difficult to filter the events efficiently.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol33: event CohortReplaced(address[] newCohort, Cohort indexed cohort);SecurityCouncilManager.sol#L33
36: event MemberReplaced(address indexed replacedMember, address indexed newMember, Cohort cohort);SecurityCouncilManager.sol#L36
37: event MemberRotated(address indexed replacedAddress, address indexed newAddress, Cohort cohort);SecurityCouncilManager.sol#L37
38: event SecurityCouncilAdded(
39: address securityCouncil, address updateAction, uint256 securityCouncilsLength
40: );SecurityCouncilManager.sol#L38-L40
41: event SecurityCouncilRemoved(
42: address securityCouncil, address updateAction, uint256 securityCouncilsLength
43: );SecurityCouncilManager.sol#L41-L43
44: event UpgradeExecRouteBuilderSet(address UpgradeExecRouteBuilder);SecurityCouncilManager.sol#L44
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol35: event VoteCastForContender(
36: uint256 indexed proposalId,
37: address indexed voter,
38: address indexed contender,
39: uint256 votes,
40: uint256 totalUsedVotes,
41: uint256 usableVotes
42: );SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L35-L42
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol14: event UpdateNonceTooLow(
15: address indexed securityCouncil, uint256 currrentNonce, uint256 providedNonce
16: );SecurityCouncilMemberSyncAction.sol#L14-L16
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol56: event ContractsDeployed(DeployedContracts deployedContracts);L2SecurityCouncilMgmtFactory.sol#L56
The following functions could be set external to save gas and improve code quality.
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol368: function isCompliantNominee(uint256 proposalId, address account) public view returns (bool) {
369: return isNominee(proposalId, account) && !_elections[proposalId].isExcluded[account];
370: }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: }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: }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: }SecurityCouncilNomineeElectionGovernor.sol#L448-L455
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol128: function COUNTING_MODE() public pure virtual override returns (string memory) {
129: return "support=for¶ms=account&counting=threshold";
130: }SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L128-L130
133: function hasVoted(uint256 proposalId, address account) public view override returns (bool) {
134: return _elections[proposalId].votesUsed[account] > 0;
135: }SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L133-L135
143: function nomineeCount(uint256 proposalId) public view returns (uint256) {
144: return _elections[proposalId].nominees.length;
145: }SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L143-L145
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol69: function proposalVettingDeadline(uint256 proposalId) public view returns (uint256) {
70: return proposalDeadline(proposalId) + nomineeVettingDuration;
71: }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: }SecurityCouncilNomineeElectionGovernorTiming.sol#L75-L94
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol138: function proposalThreshold()
139: public
140: pure
141: override(GovernorSettingsUpgradeable, GovernorUpgradeable)
142: returns (uint256)
143: {
144: return 0;
145: }SecurityCouncilMemberElectionGovernor.sol#L138-L145
148: function quorum(uint256) public pure override returns (uint256) {
149: return 0;
150: }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: }SecurityCouncilMemberElectionGovernor.sol#L206-L213
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol16: 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: }50: function electionIndexToCohort(uint256 electionIndex) public pure returns (Cohort) {
51: return Cohort(electionIndex % 2);
52: }File:governance/src/UpgradeExecRouteBuilder.sol186: 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: }UpgradeExecRouteBuilder.sol#L186-L200
If the functions are required by an interface, the contract should inherit from that interface and use the override keyword
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol324: 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: }SecurityCouncilNomineeElectionGovernor.sol#L324-L352
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol52: function __SecurityCouncilNomineeElectionGovernorCounting_init() internal onlyInitializing {}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: }SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L62-L118
170: function _quorumReached(uint256) internal pure override returns (bool) {
171: return true;
172: }SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L170-L172
175: function _voteSucceeded(uint256) internal pure override returns (bool) {
176: return true;
177: }SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L175-L177
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol28: 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: }SecurityCouncilNomineeElectionGovernorTiming.sol#L28-L66
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol115: 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: }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: }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: }SecurityCouncilMemberElectionGovernor.sol#L164-L171
174: function _targetMemberCount() internal view override returns (uint256) {
175: return securityCouncilManager.cohortSize();
176: }SecurityCouncilMemberElectionGovernor.sol#L174-L176
File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol24: function __ArbitrumGovernorVotesQuorumFraction_init(uint256 quorumNumeratorValue)
25: internal
26: onlyInitializing
27: {
28: __GovernorVotesQuorumFraction_init(quorumNumeratorValue);
29: }ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L24-L29
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol34: function extractElectionIndex(bytes[] memory callDatas) internal pure returns (uint256) {
35: return abi.decode(callDatas[0], (uint256));
36: }File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol5: 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: }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: }SecurityCouncilMgmtUtils.sol#L15-L36
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol8: 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: }SecurityCouncilMgmtUpgradeLib.sol#L8-L27
File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol25: function _set(uint256 key, uint256 value) internal {
26: store.set(computeKey(key), value);
27: }ActionExecutionRecord.sol#L25-L27
31: function _get(uint256 key) internal view returns (uint256) {
32: return store.get(computeKey(key));
33: }ActionExecutionRecord.sol#L31-L33
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).
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol106:for (uint256 i = 0; i < _roles.memberRemovers.length; i++) {SecurityCouncilManager.sol#L106
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol118:for (uint256 i = 0; i < _securityCouncils.length; i++) {SecurityCouncilManager.sol#L118
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol135:for (uint256 i = 0; i < _newCohort.length; i++) {SecurityCouncilManager.sol#L135
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol164:for (uint256 j = 0; j < cohort.length; j++) {SecurityCouncilManager.sol#L164
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol251:for (uint256 i = 0; i < securityCouncils.length; i++) {SecurityCouncilManager.sol#L251
284:for (uint256 i = 0; i < securityCouncils.length; i++) {SecurityCouncilManager.sol#L284
392:for (uint256 i = 0; i < securityCouncils.length; i++) {SecurityCouncilManager.sol#L392
File:governance/src/UpgradeExecRouteBuilder.sol76:for (uint256 i = 0; i < _upgradeExecutors.length; i++) {UpgradeExecRouteBuilder.sol#L76
File:governance/src/UpgradeExecRouteBuilder.sol129:for (uint256 i = 0; i < chainIds.length; i++) {UpgradeExecRouteBuilder.sol#L129
193:for (uint256 i = 0; i < chainIds.length; i++) {UpgradeExecRouteBuilder.sol#L193
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol60:for (uint256 i = 0; i < _updatedMembers.length; i++) {SecurityCouncilMemberSyncAction.sol#L60
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol67:for (uint256 i = 0; i < previousOwners.length; i++) {SecurityCouncilMemberSyncAction.sol#L67
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol105:for (uint256 i = 0; i < owners.length; i++) {SecurityCouncilMemberSyncAction.sol#L105
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol6:for (uint256 i = 0; i < arr.length; i++) {SecurityCouncilMgmtUtils.sol#L6
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol22:for (uint256 i = 0; i < input.length; i++) {SecurityCouncilMgmtUtils.sol#L22
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol111:for (uint256 i = 0; i < dp.firstCohort.length; i++) {L2SecurityCouncilMgmtFactory.sol#L111
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol117:for (uint256 i = 0; i < dp.secondCohort.length; i++) {L2SecurityCouncilMgmtFactory.sol#L117
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol61:for (uint256 i = 0; i < array1.length; i++) {SecurityCouncilMgmtUpgradeLib.sol#L61
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol63:for (uint256 j = 0; j < array2.length; j++) {SecurityCouncilMgmtUpgradeLib.sol#L63
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol74:for (uint256 i = 0; i < array2.length; i++) {SecurityCouncilMgmtUpgradeLib.sol#L74
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol76:for (uint256 j = 0; j < array1.length; j++) {SecurityCouncilMgmtUpgradeLib.sol#L76
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol176:function addMember(address _newMember, Cohort _cohort) external onlyRole(MEMBER_ADDER_ROLE) {SecurityCouncilManager.sol#L176
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol183:function removeMember(address _member) external onlyRole(MEMBER_REMOVER_ROLE) {SecurityCouncilManager.sol#L183
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol246:function setNomineeVetter(address _nomineeVetter) external onlyGovernance {SecurityCouncilNomineeElectionGovernor.sol#L246
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol290:function includeNominee(uint256 proposalId, address account) external onlyNomineeVetter {SecurityCouncilNomineeElectionGovernor.sol#L290
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol52:function __SecurityCouncilNomineeElectionGovernorCounting_init() internal onlyInitializing {}SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L52
See for more information: https://github.com/ConnorBlockchain/Solidity-Encode-Gas-Comparison
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol23:abi.encode(File:governance/src/UpgradeExecRouteBuilder.sol151:abi.encode(UpgradeExecRouteBuilder.sol#L151
File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol27:abi.encode(File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol38:abi.encode(G-4 | keccak256() EXPRESSIONS WHICH ARE FIXED, CAN BE PRECALCULATED AND ASSIGNED TO THE CONSTANT VARIABLES.
Instead of calculating the keccak256() when the contract is made, pre calculate them before and only give the result to a constant
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol79:constant COHORT_REPLACER_ROLE = keccak256("COHORT_REPLACER");SecurityCouncilManager.sol#L79
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol80:constant MEMBER_ADDER_ROLE = keccak256("MEMBER_ADDER");SecurityCouncilManager.sol#L80
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol81:constant MEMBER_REPLACER_ROLE = keccak256("MEMBER_REPLACER");SecurityCouncilManager.sol#L81
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol82:constant MEMBER_ROTATOR_ROLE = keccak256("MEMBER_ROTATOR");SecurityCouncilManager.sol#L82
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol83:constant MEMBER_REMOVER_ROLE = keccak256("MEMBER_REMOVER");SecurityCouncilManager.sol#L83
The compiler uses opcodes GT and ISZERO for solidity code that uses >, but only requires LT for >=, which saves 3 gas
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol106: < _SecurityCouncilManager.sol#L106
118: < _SecurityCouncilManager.sol#L118
135: < _SecurityCouncilManager.sol#L135
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol128: > 5SecurityCouncilNomineeElectionGovernor.sol#L128
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol151: > vSecurityCouncilNomineeElectionGovernor.sol#L151
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol167: < tSecurityCouncilNomineeElectionGovernor.sol#L167
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol321: > tSecurityCouncilNomineeElectionGovernor.sol#L321
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol339: < cSecurityCouncilNomineeElectionGovernor.sol#L339
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol396: < 2SecurityCouncilNomineeElectionGovernor.sol#L396
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol90: > wSecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L90
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol134: > 0SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L134
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol56: > _SecurityCouncilMemberElectionGovernor.sol#L56
File:governance/src/UpgradeExecRouteBuilder.sol76: < _UpgradeExecRouteBuilder.sol#L76
File:governance/src/UpgradeExecRouteBuilder.sol129: < cUpgradeExecRouteBuilder.sol#L129
193: < cUpgradeExecRouteBuilder.sol#L193
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol60: < _SecurityCouncilMemberSyncAction.sol#L60
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol67: < pSecurityCouncilMemberSyncAction.sol#L67
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol105: < oSecurityCouncilMemberSyncAction.sol#L105
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol6: < aSecurityCouncilMgmtUtils.sol#L6
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol22: < iSecurityCouncilMgmtUtils.sol#L22
31: < iSecurityCouncilMgmtUtils.sol#L31
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol111: < dL2SecurityCouncilMgmtFactory.sol#L111
117: < dL2SecurityCouncilMgmtFactory.sol#L117
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol61: < aSecurityCouncilMgmtUpgradeLib.sol#L61
63: < aSecurityCouncilMgmtUpgradeLib.sol#L63
74: < aSecurityCouncilMgmtUpgradeLib.sol#L74
76: < aSecurityCouncilMgmtUpgradeLib.sol#L76
Saves 5 gas per loop
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol106:i++SecurityCouncilManager.sol#L106
118:i++SecurityCouncilManager.sol#L118
135:i++SecurityCouncilManager.sol#L135
162:i++SecurityCouncilManager.sol#L162
251:i++SecurityCouncilManager.sol#L251
284:i++SecurityCouncilManager.sol#L284
339:i++SecurityCouncilManager.sol#L339
342:i++SecurityCouncilManager.sol#L342
392:i++SecurityCouncilManager.sol#L392
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol180:electionCount++SecurityCouncilNomineeElectionGovernor.sol#L180
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol280:election.excludedNomineeCount++SecurityCouncilNomineeElectionGovernor.sol#L280
File:governance/src/UpgradeExecRouteBuilder.sol76:i++UpgradeExecRouteBuilder.sol#L76
129:i++UpgradeExecRouteBuilder.sol#L129
193:i++UpgradeExecRouteBuilder.sol#L193
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol60:i++SecurityCouncilMemberSyncAction.sol#L60
67:i++SecurityCouncilMemberSyncAction.sol#L67
105:i++SecurityCouncilMemberSyncAction.sol#L105
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol6:i++SecurityCouncilMgmtUtils.sol#L6
22:i++SecurityCouncilMgmtUtils.sol#L22
31:i++SecurityCouncilMgmtUtils.sol#L31
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol111:i++L2SecurityCouncilMgmtFactory.sol#L111
117:i++L2SecurityCouncilMgmtFactory.sol#L117
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol61:i++SecurityCouncilMgmtUpgradeLib.sol#L61
74:i++SecurityCouncilMgmtUpgradeLib.sol#L74
Using the addition operator instead of plus-equals saves 113 gas
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol79:+=SecurityCouncilNomineeElectionGovernorTiming.sol#L79
84:+=SecurityCouncilNomineeElectionGovernorTiming.sol#L84
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
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol433:uint8SecurityCouncilNomineeElectionGovernor.sol#L433
438:uint8SecurityCouncilNomineeElectionGovernor.sol#L438
448:uint8SecurityCouncilNomineeElectionGovernor.sol#L448
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol50:uint8SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L50
65:uint8SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L65
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol191:uint8SecurityCouncilMemberElectionGovernor.sol#L191
196:uint8SecurityCouncilMemberElectionGovernor.sol#L196
206:uint8SecurityCouncilMemberElectionGovernor.sol#L206
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol119:uint16SecurityCouncilMemberSyncAction.sol#L119
123:uint16SecurityCouncilMemberSyncAction.sol#L123
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol34:uint64L2SecurityCouncilMgmtFactory.sol#L34
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
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol77:public constant RETRYABLE_TICKET_MAGIC =SecurityCouncilManager.sol#L77
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol79:public constant COHORT_REPLACER_ROLE =SecurityCouncilManager.sol#L79
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol80:public constant MEMBER_ADDER_ROLE =SecurityCouncilManager.sol#L80
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol81:public constant MEMBER_REPLACER_ROLE =SecurityCouncilManager.sol#L81
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol82:public constant MEMBER_ROTATOR_ROLE =SecurityCouncilManager.sol#L82
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol83:public constant MEMBER_REMOVER_ROLE =SecurityCouncilManager.sol#L83
File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol22:public constant EXCLUDE_ADDRESS =ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L22
File:governance/src/UpgradeExecRouteBuilder.sol47:public constant RETRYABLE_TICKET_MAGIC =UpgradeExecRouteBuilder.sol#L47
File:governance/src/UpgradeExecRouteBuilder.sol50:public constant DEFAULT_GOV_ACTION_CALLDATA =UpgradeExecRouteBuilder.sol#L50
File:governance/src/UpgradeExecRouteBuilder.sol52:public constant DEFAULT_VALUE =UpgradeExecRouteBuilder.sol#L52
File:governance/src/UpgradeExecRouteBuilder.sol54:public constant DEFAULT_PREDECESSOR =UpgradeExecRouteBuilder.sol#L54
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol19:public constant SENTINEL_OWNERS =SecurityCouncilMemberSyncAction.sol#L19
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 .
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol106:uint256 i = 0;SecurityCouncilManager.sol#L106
118:uint256 i = 0;SecurityCouncilManager.sol#L118
135:uint256 i = 0;SecurityCouncilManager.sol#L135
162:uint256 i = 0;SecurityCouncilManager.sol#L162
251:uint256 i = 0;SecurityCouncilManager.sol#L251
284:uint256 i = 0;SecurityCouncilManager.sol#L284
339:uint256 i = 0;SecurityCouncilManager.sol#L339
342:uint256 i = 0;SecurityCouncilManager.sol#L342
392:uint256 i = 0;SecurityCouncilManager.sol#L392
File:governance/src/UpgradeExecRouteBuilder.sol52:uint256 public constant DEFAULT_VALUE = 0;UpgradeExecRouteBuilder.sol#L52
File:governance/src/UpgradeExecRouteBuilder.sol76:uint256 i = 0;UpgradeExecRouteBuilder.sol#L76
129:uint256 i = 0;UpgradeExecRouteBuilder.sol#L129
193:uint256 i = 0;UpgradeExecRouteBuilder.sol#L193
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol60:uint256 i = 0;SecurityCouncilMemberSyncAction.sol#L60
67:uint256 i = 0;SecurityCouncilMemberSyncAction.sol#L67
105:uint256 i = 0;SecurityCouncilMemberSyncAction.sol#L105
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol6:uint256 i = 0;SecurityCouncilMgmtUtils.sol#L6
22:uint256 i = 0;SecurityCouncilMgmtUtils.sol#L22
31:uint256 i = 0;SecurityCouncilMgmtUtils.sol#L31
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol111:uint256 i = 0;L2SecurityCouncilMgmtFactory.sol#L111
117:uint256 i = 0;L2SecurityCouncilMgmtFactory.sol#L117
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol61:uint256 i = 0;SecurityCouncilMgmtUpgradeLib.sol#L61
74:uint256 i = 0;SecurityCouncilMgmtUpgradeLib.sol#L74
Flipping the true and false blocks instead saves 3 gas
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol133:== Cohort.FIRST ?SecurityCouncilManager.sol#L133
147:== Cohort.FIRST ?SecurityCouncilManager.sol#L147
365:== Cohort.FIRST ?SecurityCouncilManager.sol#L365
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol390:== 0 ?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
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
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol106:i++SecurityCouncilManager.sol#L106
118:i++SecurityCouncilManager.sol#L118
135:i++SecurityCouncilManager.sol#L135
162:i++SecurityCouncilManager.sol#L162
251:i++SecurityCouncilManager.sol#L251
284:i++SecurityCouncilManager.sol#L284
339:i++SecurityCouncilManager.sol#L339
342:i++SecurityCouncilManager.sol#L342
392:i++SecurityCouncilManager.sol#L392
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol180:electionCount++SecurityCouncilNomineeElectionGovernor.sol#L180
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol280:election.excludedNomineeCount++SecurityCouncilNomineeElectionGovernor.sol#L280
File:governance/src/UpgradeExecRouteBuilder.sol76:i++UpgradeExecRouteBuilder.sol#L76
129:i++UpgradeExecRouteBuilder.sol#L129
193:i++UpgradeExecRouteBuilder.sol#L193
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol60:i++SecurityCouncilMemberSyncAction.sol#L60
67:i++SecurityCouncilMemberSyncAction.sol#L67
105:i++SecurityCouncilMemberSyncAction.sol#L105
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol6:i++SecurityCouncilMgmtUtils.sol#L6
22:i++SecurityCouncilMgmtUtils.sol#L22
31:i++SecurityCouncilMgmtUtils.sol#L31
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol111:i++L2SecurityCouncilMgmtFactory.sol#L111
117:i++L2SecurityCouncilMgmtFactory.sol#L117
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol61:i++SecurityCouncilMgmtUpgradeLib.sol#L61
74:i++SecurityCouncilMgmtUpgradeLib.sol#L74
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol133: delete firstCohort : delete secondCohort;SecurityCouncilManager.sol#L133
It is cheaper to use != 0 than > 0 for uint256.
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol134:> 0SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L134
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.
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol128: / pSecurityCouncilNomineeElectionGovernor.sol#L128
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol80: / 1SecurityCouncilNomineeElectionGovernorTiming.sol#L80
File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol40: / qArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L40
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol85:constructorSecurityCouncilManager.sol#L85
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol98:constructorSecurityCouncilNomineeElectionGovernor.sol#L98
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol38:constructorSecurityCouncilMemberElectionGovernor.sol#L38
File:governance/src/UpgradeExecRouteBuilder.sol67:constructorUpgradeExecRouteBuilder.sol#L67
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol21:constructorSecurityCouncilMemberSyncAction.sol#L21
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol25:constructorGovernanceChainSCMgmtActivationAction.sol#L25
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol16:constructorL1SCMgmtActivationAction.sol#L16
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol13:constructorNonGovernanceChainSCMgmtActivationAction.sol#L13
File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol18:constructorSee this link for the full details
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol2:pragma solidity File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol2:pragma solidity SecurityCouncilNomineeElectionGovernor.sol#L2
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol2:pragma solidity SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L2
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol2:pragma solidity SecurityCouncilNomineeElectionGovernorTiming.sol#L2
File:governance/src/security-council-mgmt/governors/SecurityCouncilMemberElectionGovernor.sol2:pragma solidity SecurityCouncilMemberElectionGovernor.sol#L2
File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol2:pragma solidity ArbitrumGovernorVotesQuorumFractionUpgradeable.sol#L2
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol3:pragma solidity File:governance/src/UpgradeExecRouteBuilder.sol2:pragma solidity UpgradeExecRouteBuilder.sol#L2
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol2:pragma solidity SecurityCouncilMemberSyncAction.sol#L2
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol2:pragma solidity SecurityCouncilMgmtUtils.sol#L2
File:governance/src/security-council-mgmt/Common.sol2:pragma solidity File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol2:pragma solidity L2SecurityCouncilMgmtFactory.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/GovernanceChainSCMgmtActivationAction.sol2:pragma solidity GovernanceChainSCMgmtActivationAction.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/L1SCMgmtActivationAction.sol2:pragma solidity L1SCMgmtActivationAction.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/NonGovernanceChainSCMgmtActivationAction.sol2:pragma solidity NonGovernanceChainSCMgmtActivationAction.sol#L2
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol2:pragma solidity SecurityCouncilMgmtUpgradeLib.sol#L2
File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol2:pragma solidity File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol2:pragma solidity hash can be done by use of assembly instead of keccak256(abi.encodePacked()) see
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol375:keccak256(abi.encodePacked(_SecurityCouncilManager.sol#L375
Use bytes32 instead of string to save gas whenever possible. String is a dynamic data structure and therefore is more gas consuming then bytes32.
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol128:(string memory)SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L128
File:governance/src/security-council-mgmt/governors/modules/ElectionGovernor.sol43:(string memory)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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol79:constant COHORT_REPLACER_ROLE = keccak256("COHORT_REPLACER");SecurityCouncilManager.sol#L79
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol80:constant MEMBER_ADDER_ROLE = keccak256("MEMBER_ADDER");SecurityCouncilManager.sol#L80
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol81:constant MEMBER_REPLACER_ROLE = keccak256("MEMBER_REPLACER");SecurityCouncilManager.sol#L81
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol82:constant MEMBER_ROTATOR_ROLE = keccak256("MEMBER_ROTATOR");SecurityCouncilManager.sol#L82
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol83:constant MEMBER_REMOVER_ROLE = keccak256("MEMBER_REMOVER");SecurityCouncilManager.sol#L83
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol79:keccak256("COHORT_REPLACER");SecurityCouncilManager.sol#L79
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol80:keccak256("MEMBER_ADDER");SecurityCouncilManager.sol#L80
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol81:keccak256("MEMBER_REPLACER");SecurityCouncilManager.sol#L81
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol82:keccak256("MEMBER_ROTATOR");SecurityCouncilManager.sol#L82
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol83:keccak256("MEMBER_REMOVER");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
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.
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol55:mapping(SecurityCouncilNomineeElectionGovernor.sol#L55
56:mapping(SecurityCouncilNomineeElectionGovernor.sol#L56
74:mapping(SecurityCouncilNomineeElectionGovernor.sol#L74
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol19:mapping(SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L19
20:mapping(SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L20
22:mapping(SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L22
26:mapping(SecurityCouncilNomineeElectionGovernorCountingUpgradeable.sol#L26
File:governance/src/UpgradeExecRouteBuilder.sol62:mapping(UpgradeExecRouteBuilder.sol#L62
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol17:mapping(SecurityCouncilMgmtUtils.sol#L17
File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol7:mapping(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.
File:governance/src/UpgradeExecRouteBuilder.sol147: else {UpgradeExecRouteBuilder.sol#L147
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.
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol222:if (_addressToRemove == address(0) || _addressToAdd == address(0)SecurityCouncilManager.sol#L222
File:governance/src/gov-action-contracts/execution-record/KeyValueStore.sol27:uint256(keccak256(abi.encode(owner, key)File:governance/src/gov-action-contracts/execution-record/ActionExecutionRecord.sol38:uint256(keccak256(abi.encode(actionContractId, key)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
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol106:for (uint256 i = 0; i < _roles.memberRemovers.length; i++)SecurityCouncilManager.sol#L106
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol118:for (uint256 i = 0; i < _securityCouncils.length; i++)SecurityCouncilManager.sol#L118
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol135:for (uint256 i = 0; i < _newCohort.length; i++)SecurityCouncilManager.sol#L135
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol164:for (uint256 j = 0; j < cohort.length; j++)SecurityCouncilManager.sol#L164
File:governance/src/security-council-mgmt/SecurityCouncilManager.sol251:for (uint256 i = 0; i < securityCouncils.length; i++)SecurityCouncilManager.sol#L251
284:for (uint256 i = 0; i < securityCouncils.length; i++)SecurityCouncilManager.sol#L284
392:for (uint256 i = 0; i < securityCouncils.length; i++)SecurityCouncilManager.sol#L392
File:governance/src/UpgradeExecRouteBuilder.sol76:for (uint256 i = 0; i < _upgradeExecutors.length; i++)UpgradeExecRouteBuilder.sol#L76
File:governance/src/UpgradeExecRouteBuilder.sol129:for (uint256 i = 0; i < chainIds.length; i++)UpgradeExecRouteBuilder.sol#L129
193:for (uint256 i = 0; i < chainIds.length; i++)UpgradeExecRouteBuilder.sol#L193
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol60:for (uint256 i = 0; i < _updatedMembers.length; i++)SecurityCouncilMemberSyncAction.sol#L60
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol67:for (uint256 i = 0; i < previousOwners.length; i++)SecurityCouncilMemberSyncAction.sol#L67
File:governance/src/security-council-mgmt/SecurityCouncilMemberSyncAction.sol105:for (uint256 i = 0; i < owners.length; i++)SecurityCouncilMemberSyncAction.sol#L105
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol6:for (uint256 i = 0; i < arr.length; i++)SecurityCouncilMgmtUtils.sol#L6
File:governance/src/security-council-mgmt/SecurityCouncilMgmtUtils.sol22:for (uint256 i = 0; i < input.length; i++)SecurityCouncilMgmtUtils.sol#L22
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol111:for (uint256 i = 0; i < dp.firstCohort.length; i++)L2SecurityCouncilMgmtFactory.sol#L111
File:governance/src/security-council-mgmt/factories/L2SecurityCouncilMgmtFactory.sol117:for (uint256 i = 0; i < dp.secondCohort.length; i++)L2SecurityCouncilMgmtFactory.sol#L117
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol61:for (uint256 i = 0; i < array1.length; i++)SecurityCouncilMgmtUpgradeLib.sol#L61
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol63:for (uint256 j = 0; j < array2.length; j++)SecurityCouncilMgmtUpgradeLib.sol#L63
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol74:for (uint256 i = 0; i < array2.length; i++)SecurityCouncilMgmtUpgradeLib.sol#L74
File:governance/src/gov-action-contracts/AIPs/SecurityCouncilMgmt/SecurityCouncilMgmtUpgradeLib.sol76:for (uint256 j = 0; j < array1.length; j++)SecurityCouncilMgmtUpgradeLib.sol#L76
File:governance/src/security-council-mgmt/governors/SecurityCouncilNomineeElectionGovernor.sol128: if ((quorumDenominator() / SecurityCouncilNomineeElectionGovernor.sol#L128
File:governance/src/security-council-mgmt/governors/modules/SecurityCouncilNomineeElectionGovernorTiming.sol80: uint256 year = firstNominationStartDate.year + month / SecurityCouncilNomineeElectionGovernorTiming.sol#L80
File:governance/src/security-council-mgmt/governors/modules/ArbitrumGovernorVotesQuorumFractionUpgradeable.sol40: /