Skip to content

Instantly share code, notes, and snippets.

@Picodes
Created March 3, 2023 21:12
Show Gist options
  • Save Picodes/16984274f6ad7b83b7a59f8b33cee6a6 to your computer and use it in GitHub Desktop.
Save Picodes/16984274f6ad7b83b7a59f8b33cee6a6 to your computer and use it in GitHub Desktop.

Report

Gas Optimizations

Issue Instances
GAS-1 Use assembly to check for address(0) 22
GAS-2 array[index] += amount is cheaper than array[index] = array[index] + amount (or related variants) 1
GAS-3 Using bools for storage incurs overhead 2
GAS-4 Cache array length outside of loop 10
GAS-5 State variables should be cached in stack variables rather than re-reading them from storage 1
GAS-6 Use calldata instead of memory for function arguments that do not get mutated 20
GAS-7 Don't initialize variables with default value 1
GAS-8 Functions guaranteed to revert when called by normal users can be marked payable 4
GAS-9 ++i costs less gas than i++, especially when it's used in for-loops (--i/i-- too) 1
GAS-10 Using private rather than public for constants, saves gas 29
GAS-11 Use shift Right/Left instead of division/multiplication if possible 2
GAS-12 Use != 0 instead of > 0 for unsigned integer comparison 9

[GAS-1] Use assembly to check for address(0)

Saves 6 gas per instance

Instances (22):

File: packages/contracts/src/core/dao/DAO.sol

225:         if (_token == address(0)) {

252:         if (address(signatureValidator) == address(0)) {

Link to code

File: packages/contracts/src/framework/plugin/setup/PluginSetupProcessor.sol

321:         if (pluginState.currentAppliedSetupId != bytes32(0)) {

366:         if (pluginState.currentAppliedSetupId != bytes32(0)) {

Link to code

File: packages/contracts/src/framework/utils/TokenFactory.sol

86:         if (token != address(0)) {

Link to code

File: packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol

65:         if (nodeResolver == address(0)) {

89:         if (currentOwner != address(0)) {

103:         if (_resolver == address(0)) {

Link to code

File: packages/contracts/src/plugins/counter-example/v1/CounterV1PluginSetup.sol

43:         if (_multiplyHelper == address(0)) {

56:                 _multiplyHelper == address(0) ? 3 : 2

80:         if (_multiplyHelper == address(0)) {

Link to code

File: packages/contracts/src/plugins/counter-example/v2/CounterV2PluginSetup.sol

44:         if (_multiplyHelper == address(0)) {

57:                 _multiplyHelper == address(0) ? 3 : 2

81:         if (_multiplyHelper == address(0)) {

Link to code

File: packages/contracts/src/plugins/governance/admin/AdminSetup.sol

39:         if (admin == address(0)) {

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/token/TokenVotingSetup.sol

98:         if (token != address(0)) {

151:                 tokenSettings.addr != address(0) ? 3 : 4

181:         if (tokenSettings.addr == address(0)) {

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceERC20.sol

116:         if (to != address(0) && numCheckpoints(to) == 0 && delegates(to) == address(0)) {

116:         if (to != address(0) && numCheckpoints(to) == 0 && delegates(to) == address(0)) {

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceWrappedERC20.sol

106:         if (to != address(0) && numCheckpoints(to) == 0 && delegates(to) == address(0)) {

106:         if (to != address(0) && numCheckpoints(to) == 0 && delegates(to) == address(0)) {

Link to code

[GAS-2] array[index] += amount is cheaper than array[index] = array[index] + amount (or related variants)

When updating a value in an array with arithmetic, using array[index] += amount is cheaper than array[index] = array[index] + amount. This is because you avoid an additonal mload when the array is stored in memory, and an sload when the array is stored in storage. This can be applied for any arithmetic operation including +=, -=,/=,*=,^=,&=, %=, <<=,>>=, and >>>=. This optimization can be particularly significant if the pattern occurs during a loop.

Saves 28 gas for a storage array, 38 for a memory array

Instances (1):

File: packages/contracts/src/plugins/token/MerkleDistributor.sol

123:         claimedBitMap[claimedWord_index] =

Link to code

[GAS-3] Using bools for storage incurs overhead

Use uint256(1) and uint256(2) for true/false to avoid a Gwarmaccess (100 gas), and to avoid Gsset (20000 gas) when changing from ‘false’ to ‘true’, after having been ‘true’ in the past. See source.

Instances (2):

File: packages/contracts/src/framework/utils/InterfaceBasedRegistry.sol

25:     mapping(address => bool) public entries;

Link to code

File: packages/contracts/src/plugins/governance/multisig/Multisig.sol

38:         mapping(address => bool) approvers;

Link to code

[GAS-4] Cache array length outside of loop

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).

Instances (10):

File: packages/contracts/src/core/dao/DAO.sol

184:         for (uint256 i = 0; i < _actions.length; ) {

Link to code

File: packages/contracts/src/core/permission/PermissionManager.sol

150:         for (uint256 i; i < items.length; ) {

170:         for (uint256 i; i < _items.length; ) {

Link to code

File: packages/contracts/src/framework/dao/DAOFactory.sol

95:         for (uint256 i; i < _pluginSettings.length; ++i) {

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/addresslist/AddresslistVoting.sol

130:         for (uint256 i; i < _actions.length; ) {

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol

124:         for (uint256 i; i < _actions.length; ) {

Link to code

File: packages/contracts/src/plugins/governance/multisig/Multisig.sol

252:         for (uint256 i; i < _actions.length; ) {

Link to code

File: packages/contracts/src/plugins/utils/Addresslist.sol

60:         for (uint256 i; i < _newAddresses.length; ) {

78:         for (uint256 i; i < _exitingAddresses.length; ) {

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceERC20.sol

81:         for (uint256 i; i < _mintSettings.receivers.length; ) {

Link to code

[GAS-5] State variables should be cached in stack variables rather than re-reading them from storage

The instances below point to the second+ access of a state variable within a function. Caching of a state variable replaces each Gwarmaccess (100 gas) with a much cheaper stack read. Other less obvious fixes/optimizations include having local memory caches of state variable structs, or having local caches of state variable contracts/addresses.

Saves 100 gas per instance

Instances (1):

File: packages/contracts/src/framework/utils/TokenFactory.sol

128:         emit TokenCreated(IERC20Upgradeable(token), MerkleMinter(merkleMinter), distributorBase);

Link to code

[GAS-6] Use calldata instead of memory for function arguments that do not get mutated

Mark data types as calldata instead of memory where possible. This makes it so that the data is not automatically loaded into memory. If the data passed into the function does not need to be changed (like updating values in an array), it can be passed in as calldata. The one exception to this is if the argument must later be passed into another function that takes an argument that specifies memory storage.

Instances (20):

File: packages/contracts/src/core/dao/DAO.sol

155:         bytes memory _data

250:         bytes memory _signature

Link to code

File: packages/contracts/src/core/dao/IDAO.sol

29:         bytes memory _data

48:         Action[] memory _actions,

125:     function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4);

Link to code

File: packages/contracts/src/core/permission/PermissionManager.sol

202:         bytes memory _data

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepoFactory.sol

49:         bytes memory _releaseMetadata,

50:         bytes memory _buildMetadata

Link to code

File: packages/contracts/src/plugins/token/IMerkleDistributor.sol

45:         bytes32[] memory _proof

Link to code

File: packages/contracts/src/plugins/token/MerkleDistributor.sol

87:         bytes32[] memory _proof

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceERC20.sol

51:         string memory _name,

52:         string memory _symbol,

53:         MintSettings memory _mintSettings

65:         string memory _name,

66:         string memory _symbol,

67:         MintSettings memory _mintSettings

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceWrappedERC20.sol

38:     constructor(IERC20Upgradeable _token, string memory _name, string memory _symbol) {

38:     constructor(IERC20Upgradeable _token, string memory _name, string memory _symbol) {

48:         string memory _name,

49:         string memory _symbol

Link to code

[GAS-7] Don't initialize variables with default value

Instances (1):

File: packages/contracts/src/core/dao/DAO.sol

184:         for (uint256 i = 0; i < _actions.length; ) {

Link to code

[GAS-8] Functions guaranteed to revert when called by normal users can be marked payable

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.

Instances (4):

File: packages/contracts/src/core/permission/PermissionManager.sol

95:     function __PermissionManager_init(address _initialOwner) internal onlyInitializing {

Link to code

File: packages/contracts/src/core/plugin/PluginCloneable.sol

22:     function __PluginCloneable_init(IDAO _dao) internal virtual onlyInitializing {

Link to code

File: packages/contracts/src/core/plugin/PluginUUPSUpgradeable.sol

39:     function __PluginUUPSUpgradeable_init(IDAO _dao) internal virtual onlyInitializing {

Link to code

File: packages/contracts/src/core/plugin/dao-authorizable/DaoAuthorizableUpgradeable.sol

20:     function __DaoAuthorizableUpgradeable_init(IDAO _dao) internal onlyInitializing {

Link to code

[GAS-9] ++i costs less gas than i++, especially when it's used in for-loops (--i/i-- too)

Saves 5 gas per loop

Instances (1):

File: packages/contracts/src/framework/utils/RegistryUtils.sol

16:     for (uint256 i; i < nameLength; i++) {

Link to code

[GAS-10] Using private rather than public for constants, saves gas

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

Instances (29):

File: packages/contracts/src/core/dao/DAO.sol

40:     bytes32 public constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION");

43:     bytes32 public constant UPGRADE_DAO_PERMISSION_ID = keccak256("UPGRADE_DAO_PERMISSION");

46:     bytes32 public constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION");

49:     bytes32 public constant SET_TRUSTED_FORWARDER_PERMISSION_ID =

53:     bytes32 public constant SET_SIGNATURE_VALIDATOR_PERMISSION_ID =

57:     bytes32 public constant REGISTER_STANDARD_CALLBACK_PERMISSION_ID =

Link to code

File: packages/contracts/src/core/permission/PermissionLib.sol

10:     address public constant NO_CONDITION = address(0);

Link to code

File: packages/contracts/src/core/permission/PermissionManager.sol

15:     bytes32 public constant ROOT_PERMISSION_ID = keccak256("ROOT_PERMISSION");

Link to code

File: packages/contracts/src/core/plugin/PluginUUPSUpgradeable.sol

35:     bytes32 public constant UPGRADE_PLUGIN_PERMISSION_ID = keccak256("UPGRADE_PLUGIN_PERMISSION");

Link to code

File: packages/contracts/src/framework/dao/DAORegistry.sol

15:     bytes32 public constant REGISTER_DAO_PERMISSION_ID = keccak256("REGISTER_DAO_PERMISSION");

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepo.sol

49:     bytes32 public constant MAINTAINER_PERMISSION_ID = keccak256("MAINTAINER_PERMISSION");

52:     bytes32 public constant UPGRADE_REPO_PERMISSION_ID = keccak256("UPGRADE_REPO_PERMISSION");

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol

16:     bytes32 public constant REGISTER_PLUGIN_REPO_PERMISSION_ID =

Link to code

File: packages/contracts/src/framework/plugin/setup/PluginSetupProcessor.sol

27:     bytes32 public constant APPLY_INSTALLATION_PERMISSION_ID =

31:     bytes32 public constant APPLY_UPDATE_PERMISSION_ID = keccak256("APPLY_UPDATE_PERMISSION");

34:     bytes32 public constant APPLY_UNINSTALLATION_PERMISSION_ID =

Link to code

File: packages/contracts/src/framework/utils/InterfaceBasedRegistry.sol

18:     bytes32 public constant UPGRADE_REGISTRY_PERMISSION_ID =

Link to code

File: packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol

18:     bytes32 public constant UPGRADE_REGISTRAR_PERMISSION_ID =

22:     bytes32 public constant REGISTER_ENS_SUBDOMAIN_PERMISSION_ID =

Link to code

File: packages/contracts/src/plugins/counter-example/MultiplyHelper.sol

12:     bytes32 public constant MULTIPLY_PERMISSION_ID = keccak256("MULTIPLY_PERMISSION");

Link to code

File: packages/contracts/src/plugins/counter-example/v1/CounterV1.sol

14:     bytes32 public constant MULTIPLY_PERMISSION_ID = keccak256("MULTIPLY_PERMISSION");

Link to code

File: packages/contracts/src/plugins/counter-example/v2/CounterV2.sol

14:     bytes32 public constant MULTIPLY_PERMISSION_ID = keccak256("MULTIPLY_PERMISSION");

Link to code

File: packages/contracts/src/plugins/governance/admin/Admin.sol

23:     bytes32 public constant EXECUTE_PROPOSAL_PERMISSION_ID =

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/MajorityVotingBase.sol

183:     bytes32 public constant UPDATE_VOTING_SETTINGS_PERMISSION_ID =

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/addresslist/AddresslistVoting.sol

27:     bytes32 public constant UPDATE_ADDRESSES_PERMISSION_ID =

Link to code

File: packages/contracts/src/plugins/governance/multisig/Multisig.sol

71:     bytes32 public constant UPDATE_MULTISIG_SETTINGS_PERMISSION_ID =

Link to code

File: packages/contracts/src/plugins/token/MerkleMinter.sol

24:     bytes32 public constant MERKLE_MINT_PERMISSION_ID = keccak256("MERKLE_MINT_PERMISSION");

27:     bytes32 public constant CHANGE_DISTRIBUTOR_PERMISSION_ID =

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceERC20.sol

28:     bytes32 public constant MINT_PERMISSION_ID = keccak256("MINT_PERMISSION");

Link to code

[GAS-11] Use shift Right/Left instead of division/multiplication if possible

Instances (2):

File: packages/contracts/src/plugins/token/MerkleDistributor.sol

111:         uint256 claimedWord_index = _index / 256;

121:         uint256 claimedWord_index = _index / 256;

Link to code

[GAS-12] Use != 0 instead of > 0 for unsigned integer comparison

Instances (9):

File: packages/contracts/src/core/utils/BitMap.sol

10:     return bitValue > 0;

Link to code

File: packages/contracts/src/framework/dao/DAORegistry.sol

59:         if ((bytes(subdomain).length > 0)) {

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepo.sol

181:         if (_releaseMetadata.length > 0) {

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol

55:         if (!(bytes(subdomain).length > 0)) {

Link to code

File: packages/contracts/src/framework/plugin/setup/PluginSetupProcessor.sol

378:         if (_params.permissions.length > 0) {

535:         if (_params.permissions.length > 0) {

635:         if (_params.permissions.length > 0) {

669:         if (_initData.length > 0) {

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol

139:         return votingToken.getVotes(_account) > 0;

Link to code

Non Critical Issues

Issue Instances
NC-1 Missing checks for address(0) when assigning values to address state variables 1
NC-2 Return values of approve() not checked 1
NC-3 Event is missing indexed fields 26
NC-4 Functions not used internally could be marked external 22
NC-5 Typos 167

[NC-1] Missing checks for address(0) when assigning values to address state variables

Instances (1):

File: packages/contracts/src/core/dao/DAO.sol

284:         trustedForwarder = _trustedForwarder;

Link to code

[NC-2] Return values of approve() not checked

Not all IERC20 implementations revert() when there's a failure in approve(). The function signature has a boolean return value and they indicate errors that way instead. By not checking the return value, operations that should have marked as failed, may potentially go through without actually approving anything

Instances (1):

File: packages/contracts/src/plugins/governance/multisig/Multisig.sol

260:             approve(proposalId, _tryExecution);

Link to code

[NC-3] Event is missing indexed fields

Index event fields make the field more quickly accessible to off-chain tools that parse events. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields). Each event should use three indexed fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three fields, all of the fields should be indexed.

Instances (26):

File: packages/contracts/src/core/dao/DAO.sol

89:     event NewURI(string daoURI);

Link to code

File: packages/contracts/src/core/dao/IDAO.sol

38:     event MetadataSet(bytes metadata);

59:     event Executed(

71:     event StandardCallbackRegistered(

88:     event Deposited(

99:     event NativeTokenDeposited(address sender, uint256 amount);

111:     event TrustedForwarderSet(address forwarder);

119:     event SignatureValidatorSet(address signatureValidator);

Link to code

File: packages/contracts/src/core/plugin/membership/IMembership.sol

13:     event MembersAdded(address[] members);

17:     event MembersRemoved(address[] members);

Link to code

File: packages/contracts/src/core/plugin/proposal/IProposal.sol

19:     event ProposalCreated(

Link to code

File: packages/contracts/src/core/utils/CallbackHandler.sol

25:     event CallbackReceived(address sender, bytes4 indexed sig, bytes data);

Link to code

File: packages/contracts/src/framework/dao/DAORegistry.sol

27:     event DAORegistered(address indexed dao, address indexed creator, string subdomain);

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepo.sol

99:     event VersionCreated(

109:     event ReleaseMetadataUpdated(uint8 release, bytes releaseMetadata);

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol

25:     event PluginRepoRegistered(string subdomain, address pluginRepo);

Link to code

File: packages/contracts/src/framework/plugin/setup/PluginSetupProcessor.sol

200:     event InstallationApplied(

232:     event UpdateApplied(

261:     event UninstallationApplied(

Link to code

File: packages/contracts/src/framework/utils/TokenFactory.sol

42:     event TokenCreated(

50:     event WrappedToken(GovernanceWrappedERC20 token);

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/IMajorityVoting.sol

29:     event VoteCast(

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/MajorityVotingBase.sol

226:     event VotingSettingsUpdated(

Link to code

File: packages/contracts/src/plugins/governance/multisig/Multisig.sol

119:     event MultisigSettingsUpdated(bool onlyListed, uint16 indexed minApprovals);

Link to code

File: packages/contracts/src/plugins/token/IMerkleDistributor.sol

15:     event Claimed(uint256 indexed index, address indexed to, uint256 amount);

Link to code

File: packages/contracts/src/plugins/token/IMerkleMinter.sol

18:     event MerkleMinted(

Link to code

[NC-4] Functions not used internally could be marked external

Instances (22):

File: packages/contracts/src/core/plugin/Plugin.sol

20:     function pluginType() public pure override returns (PluginType) {

Link to code

File: packages/contracts/src/core/plugin/PluginCloneable.sol

27:     function pluginType() public pure override returns (PluginType) {

Link to code

File: packages/contracts/src/core/plugin/PluginUUPSUpgradeable.sol

30:     function pluginType() public pure override returns (PluginType) {

55:     function implementation() public view returns (address) {

Link to code

File: packages/contracts/src/core/plugin/dao-authorizable/DaoAuthorizable.sol

25:     function dao() public view returns (IDAO) {

Link to code

File: packages/contracts/src/core/plugin/dao-authorizable/DaoAuthorizableUpgradeable.sol

26:     function dao() public view returns (IDAO) {

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepo.sol

209:     function getLatestVersion(uint8 _release) public view returns (Version memory) {

217:     function getLatestVersion(address _pluginSetup) public view returns (Version memory) {

244:     function buildCount(uint8 _release) public view returns (uint256) {

Link to code

File: packages/contracts/src/plugins/counter-example/v1/CounterV1.sol

39:     function multiply(uint256 _a) public view auth(MULTIPLY_PERMISSION_ID) returns (uint256) {

44:     function execute() public {

Link to code

File: packages/contracts/src/plugins/counter-example/v2/CounterV2.sol

58:     function multiply(uint256 _a) public view auth(MULTIPLY_PERMISSION_ID) returns (uint256) {

63:     function execute() public {

Link to code

File: packages/contracts/src/plugins/governance/admin/Admin.sol

38:     function supportsInterface(

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol

61:     function getVotingToken() public view returns (IVotesUpgradeable) {

Link to code

File: packages/contracts/src/plugins/governance/multisig/Multisig.sol

305:     function getProposal(

328:     function hasApproved(uint256 _proposalId, address _account) public view returns (bool) {

333:     function execute(uint256 _proposalId) public {

Link to code

File: packages/contracts/src/plugins/token/MerkleDistributor.sol

83:     function unclaimedBalance(

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceWrappedERC20.sol

71:     function decimals()

81:     function depositFor(

89:     function withdrawTo(

Link to code

[NC-5] Typos

Instances (167):

File: packages/contracts/src/core/dao/DAO.sol

- 134:     /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).
+ 134:     /// @notice Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).

- 338:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
+ 338:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).

Link to code

File: packages/contracts/src/core/dao/IDAO.sol

- 40:     /// @notice Executes a list of actions. If no failure map is provided, one failing action results in the entire excution to be reverted. If a non-zero failure map is provided, allowed actions can fail without the remaining actions being reverted.
+ 40:     /// @notice Executes a list of actions. If no failure map is provided, one failing action results in the entire execution to be reverted. If a non-zero failure map is provided, allowed actions can fail without the remaining actions being reverted.

- 87:     /// @param _reference The reference describing the deposit reason.
+ 87:     /// @param reference The reference describing the deposit reason.

Link to code

File: packages/contracts/src/core/dao/IEIP4824.sol

- 9:     /// @notice A distinct Uniform Resource Identifier (URI) pointing to a JSON object following the "EIP-4824 DAO JSON-LD Schema". This JSON file splits into four URIs: membersURI, proposalsURI, activityLogURI, and governanceURI. The membersURI should point to a JSON file that conforms to the "EIP-4824 Members JSON-LD Schema". The proposalsURI should point to a JSON file that conforms to the "EIP-4824 Proposals JSON-LD Schema". The activityLogURI should point to a JSON file that conforms to the "EIP-4824 Activity Log JSON-LD Schema". The governanceURI should point to a flatfile, normatively a .md file. Each of the JSON files named above can be statically-hosted or dynamically-generated.
+ 9:     /// @notice A distinct Uniform Resource Identifier (URI) pointing to a JSON object following the "EIP-4824 DAO JSON-LD Schema". This JSON file splits into four URIs: membersURI, proposalsURI, activityLogURI, and governanceURI. The membersURI should point to a JSON file that conforms to the "EIP-4824 Members JSON-LD Schema". The proposalsURI should point to a JSON file that conforms to the "EIP-4824 Proposals JSON-LD Schema". The activityLogURI should point to a JSON file that conforms to the "EIP-4824 Activity Log JSON-LD Schema". The governanceURI should point to a flatfile, normatively a .md file. Each of the JSON files named above can be statically hosted or dynamically generated.

Link to code

File: packages/contracts/src/core/permission/IPermissionCondition.sol

- 7: /// @notice This interface can be implemented to support more customary permissions depending on on- or off-chain state, e.g., by querying token ownershop or a secondary condition, respectively.
+ 7: /// @notice This interface can be implemented to support more customary permissions depending on on- or off-chain state, e.g., by querying token ownership or a secondary condition, respectively.

- 11:     /// @param _who The address (EOA or contract) for which the permission are checked.
+ 11:     /// @param _who The address (EOA or contract) for which the permissions are checked.

Link to code

File: packages/contracts/src/core/permission/PermissionLib.sol

- 32:     /// @notice A struct containing the information for a permission to be applied on multiple target contracts, optionally, with a conditon.
+ 32:     /// @notice A struct containing the information for a permission to be applied on multiple target contracts, optionally, with a condition.

- 34:     /// @param where The address of the target contract for which `who` recieves permission.
+ 34:     /// @param where The address of the target contract for which `who` receives permission.

Link to code

File: packages/contracts/src/core/permission/PermissionManager.sol

- 292:     /// @param _where The address of the target contract for which `_who` recieves permission.
+ 292:     /// @param _where The address of the target contract for which `_who` receives permission.

- 326:     /// @param _permissionId The permission identifier required to call the method this modifier is applied to.
+ 326:     /// @param _permissionId The permission identifier required to call the method to which this modifier is applied.

- 338:     /// @param _where The address of the target contract for which `_who` recieves permission.
+ 338:     /// @param _where The address of the target contract for which `_who` receives permission.

- 350:     /// @notice Decides if the granting permissionId is restricted when `_who = ANY_ADDR` or `_where = ANY_ADDR`.
+ 350:     /// @notice Decides if the granting permissionId is restricted when `_who == ANY_ADDR` or `_where == ANY_ADDR`.

- 353:     /// @dev By default, every permission is unrestricted and it is the derived contract's responsibility to override it. Note, that the `ROOT_PERMISSION_ID` is included not required to be set it again.
+ 353:     /// @dev By default, every permission is unrestricted and it is the derived contract's responsibility to override it. Note, that the `ROOT_PERMISSION_ID` is included and not required to be set again.

Link to code

File: packages/contracts/src/core/plugin/IPlugin.sol

- 15:     /// @notice returns the plugin's type
+ 15:     /// @notice Returns the plugin's type

Link to code

File: packages/contracts/src/core/plugin/Plugin.sol

- 13: /// @notice An abstract, non-upgradeable contract to inherit from when creating a plugin being deployed via the `new` keyword.
+ 13: /// @notice An abstract, non-upgradeable contract to inherit from when creating a plugin deployed via the `new` keyword.

Link to code

File: packages/contracts/src/core/plugin/PluginUUPSUpgradeable.sol

- 59:     /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).
+ 59:     /// @notice Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).

- 65:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
+ 65:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).

Link to code

File: packages/contracts/src/core/plugin/dao-authorizable/DaoAuthorizable.sol

- 12: /// @notice An abstract contract providing a meta-transaction compatible modifier for non-upgradeable contracts instantiated via the `new` keyword to authorize function calls through an associated DAO.
+ 12: /// @notice An abstract contract providing a meta-transaction compatible modifier for non-upgradeable contracts instantiated via the `new` keyword to authorize function calls through an associated DAO. The modifier is applied to functions that require authorization.

- 29:     /// @notice A modifier to make functions on inheriting contracts authorized. Permissions to call the function are checked through the associated DAO's permission manager.
+ 29:     /// @notice A modifier to make functions on inheriting contracts authorized. Permissions to call the function are checked through the associated DAO's permission manager. The modifier is applied to functions that require authorization.

Link to code

File: packages/contracts/src/core/plugin/dao-authorizable/DaoAuthorizableUpgradeable.sol

- 37:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
+ 37:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps))

Link to code

File: packages/contracts/src/core/plugin/membership/IMembership.sol

- 7: /// @title IProposal
+ 7: /// @title IMembership

- 9: /// @notice An interface to be implemented by DAO plugins that define membership.
+ 9: /// @notice An interface to be implemented by DAO plugins that define the membership.

Link to code

File: packages/contracts/src/core/plugin/proposal/IProposal.sol

- 7: /// @title IProposal
+ 7: /// @title IProposals

- 9: /// @notice An interface to be implemented by DAO plugins that create and execute proposals.
+ 9: /// @notice An interface to be implemented by DAO plugins that create and execute Proposals.

Link to code

File: packages/contracts/src/core/plugin/proposal/Proposal.sol

- 39:     /// @param _metadata The the proposal metadata.
+ 39:     /// @param _metadata The proposal metadata.

Link to code

File: packages/contracts/src/core/plugin/proposal/ProposalUpgradeable.sol

- 10: /// @title ProposalUgradeable
+ 10: /// @title ProposalUpgradeable

- 82:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
+ 82:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps))

Link to code

File: packages/contracts/src/core/utils/BitMap.sol

- 7: /// @return Returns `true` whether the bit is set at `index` on `bitmap`.
+ 7: /// @return Returns `true` if the bit is set at `index` on `bitmap`.

- 15: /// @return Returns a new number on which the bit is set at `index`.
+ 15: /// @return Returns a new number in which the bit is set at `index`.

Link to code

File: packages/contracts/src/core/utils/CallbackHandler.sol

- 7: /// @notice This contract handles callbacks by registering a magic number together with the callback function's selector. It provides the `_handleCallback` function that inherting have to call inside their `fallback()` function  (`_handleCallback(msg.callbackSelector, msg.data)`).  This allows to adaptively register ERC standards (e.g., [ERC-721](https://eips.ethereum.org/EIPS/eip-721), [ERC-1115](https://eips.ethereum.org/EIPS/eip-1155), or future versions of [ERC-165](https://eips.ethereum.org/EIPS/eip-165)) and returning the required magic numbers for the associated callback functions for the inheriting contract so that it doesn't need to be upgraded.
+ 7: /// @notice This contract handles callbacks by registering a magic number together with the callback function's selector. It provides the `_handleCallback` function that inheriting contracts have to call inside their `fallback()` function  (`_handleCallback(msg.callbackSelector, msg.data)`).  This allows to adaptively register ERC standards (e.g., [ERC-721](https://eips.ethereum.org/EIPS/eip-721), [ERC-1115](https://eips.ethereum.org/EIPS/eip-1155), or future versions of [ERC-165](https://eips.ethereum.org/EIPS/eip-165)) and returning the required magic numbers for the associated callback functions for the inheriting contract so that it doesn't need to be upgraded.

- 8: /// @dev This callback handling functionality is intented to be used by executor contracts (i.e., `DAO.sol`).
+ 8: /// @dev This callback handling functionality is intended to be used by executor contracts (i.e., `DAO.sol`).

Link to code

File: packages/contracts/src/core/utils/auth.sol

- 15: /// @param _where The address of the target contract for which `who` recieves permission.
+ 15: /// @param _where The address of the target contract for which `who` receives permission.

- 18: /// @param _data The optional data passed to the `PermissionCondition` registered.
+ 18: /// @param _data The optional data passed to the registered `PermissionCondition`.

Link to code

File: packages/contracts/src/framework/dao/DAORegistry.sol

- 12: /// @notice This contract provides the possiblity to register a DAO.
+ 12: /// @notice This contract provides the possibility to register a DAO.

- 17:     /// @notice The ENS subdomain registrar registering the DAO subdomains.
+ 17:     /// @notice The ENS subdomain registrar for registering the DAO subdomains.

Link to code

File: packages/contracts/src/framework/plugin/repo/IPluginRepo.sol

- 9:     /// @notice Update the metadata for release with content `@fromHex(_releaseMetadata)`.
+ 9:     /// @notice Updates the metadata for release with content `@fromHex(_releaseMetadata)`.

- 14:     /// @notice Creates a new plugin version as the latest build for an existing release number or the first build for a new release number for the provided `PluginSetup` contract address and metadata.
+ 14:     /// @notice Creates a new plugin version as the latest build for an existing release number or the first build for a new release number for the provided `PluginSetup` contract address and metadata URI.

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepo.sol

- 51:     /// @notice The ID of the permission required to call the `createVersion` function.
+ 51:     /// @notice The mapping between release and build numbers.

- 54:     /// @notice The mapping between release and build numbers.
+ 54:     /// @notice The mapping between the version hash and the corresponding version information.

- 57:     /// @notice The mapping between the version hash and the corresponding version information.
+ 57:     /// @notice The mapping between the plugin setup address and its corresponding version hash.

- 60:     /// @notice The mapping between the plugin setup address and its corresponding version hash.
+ 60:     /// @notice The ID of the latest release.

- 63:     /// @notice The ID of the latest release.
+ 63:     /// @dev The maximum release number is 255.

- 64:     /// @dev The maximum release number is 255.
+ 64:     /// @notice Thrown if a version does not exist.

- 67:     /// @notice Thrown if a version does not exist.
+ 67:     /// @param versionHash The tag hash.

- 68:     /// @param versionHash The tag hash.
+ 68:     /// @notice Thrown if a plugin setup contract does not inherit from `PluginSetup`.

- 71:     /// @notice Thrown if a plugin setup contract does not inherit from `PluginSetup`.
+ 71:     /// @notice Thrown if a release number is zero.

- 74:     /// @notice Thrown if a release number is zero.
+ 74:     /// @notice Thrown if a release number is incremented by more than one.

- 77:     /// @notice Thrown if a release number is incremented by more than one.
+ 77:     /// @param latestRelease The latest release number.

- 78:     /// @param latestRelease The latest release number.
+ 78:     /// @param newRelease The new release number.

- 79:     /// @param newRelease The new release number.
+ 79:     /// @notice Thrown if the same plugin setup contract already exists in a previous release.

- 82:     /// @notice Thrown if the same plugin setup contract exists already in a previous releases.
+ 82:     /// @param release The release number of the already existing plugin setup.

- 83:     /// @param release The release number of the already existing plugin setup.
+ 83:     /// @param build The build number of the already existing plugin setup.

- 84:     /// @param build The build number of the already existing plugin setup.
+ 84:     /// @param pluginSetup The plugin setup contract address.

- 85:     /// @param pluginSetup The plugin setup contract address.
+ 85:     /// @notice Thrown if the metadata URI is empty.

- 88:     /// @notice Thrown if the metadata URI is empty.
+ 88:     /// @notice Thrown if release does not exist.

- 91:     /// @notice Thrown if release does not exist.
+ 91:     /// @notice Thrown if the same plugin setup already exists in a previous release.

- 94:     /// @notice Thrown if the same plugin setup exists in previous releases.
+ 94:     /// @param release The release number.

- 95:     /// @param release The release number.
+ 95:     /// @param build The build number.

- 96:     /// @param build The build number.
+ 96:     /// @param pluginSetup The address of the plugin setup contract.

- 97:     /// @param pluginSetup The address of the plugin setup contract.
+ 97:     /// @param buildMetadata The build metadata URI.

- 98:     /// @param buildMetadata The build metadata URI.
+ 98:     /// @notice Thrown when a release's metadata was updated.

- 106:     /// @notice Thrown when a release's metadata was updated.
+ 106:     /// @param release The release number.

- 107:     /// @param release The release number.
+ 107:     /// @param releaseMetadata The release metadata URI.

- 108:     /// @param releaseMetadata The release metadata URI.
+ 108:     /// @dev Used to disallow initializing the implementation contract by an attacker for extra safety.

- 111:     /// @dev Used to disallow initializing the implementation contract by an attacker for extra safety.
+ 111:     /// @notice Initializes the contract by

- 116:     /// @notice Initializes the contract by
+ 116:     /// - initializing the permission manager

- 117:     /// - initializing the permission manager
+ 117:     /// - granting the `MAINTAINER_PERMISSION_ID` permission to the initial owner.

- 118:     /// - granting the `MAINTAINER_PERMISSION_ID` permission to the initial owner.
+ 118:     /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822).

- 119:     /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822).
+ 119:     /// @inheritdoc IPluginRepo

- 127:     /// @inheritdoc IPluginRepo
+ 127:         // Check that the release number is not incremented by more than one

- 142:         // Check that the release number is not incremented by more than one
+ 142:         // Make sure the same plugin setup wasn't used in previous releases.

- 155:         // Make sure the same plugin setup wasn't used in previous releases.
+ 155:     /// @inheritdoc IPluginRepo

- 186:     /// @inheritdoc IPluginRepo
+ 186:     /// @notice Returns the latest version for a given release number.

- 206:     /// @notice Returns the latest version for a given release number.
+ 206:     /// @param _release The release number.

- 207:     /// @param _release The release number.
+ 207:     /// @return The latest version of this release.

- 208:     /// @return The latest version of this release.
+ 208:     /// @notice Returns the latest version for a given plugin setup.

- 214:     /// @notice Returns the latest version for a given plugin setup.
+ 214:     /// @param _pluginSetup The plugin setup address

- 215:     /// @param _pluginSetup The plugin setup address
+ 215:     /// @return The latest version associated with the plugin Setup.

- 216:     /// @return The latest version associated with the plugin Setup.
+ 216:     /// @notice Returns the version associated with a tag.

- 221:     /// @notice Returns the version associated with a tag.
+ 221:     /// @param _tag The version tag.

- 222:     /// @param _tag The version tag.
+ 222:     /// @return The version associated with the tag.

- 223:     /// @return The version associated with the tag.
+ 223:     /// @notice Returns the version for a tag hash.

- 228:     /// @notice Returns the version for a tag hash.
+ 228:     /// @param _tagHash The tag hash.

- 229:     /// @param _tagHash The tag hash.
+ 229:     /// @return The version associated with a tag hash.

- 230:     /// @return The version associated with a tag hash.
+ 230:     /// @notice Gets the total number of builds for a given release number.

- 241:     /// @notice Gets the total number of builds for a given release number.
+ 241:     /// @param _release The release number.

- 242:     /// @param _release The release number.
+ 242:     /// @return The number of builds of this release.

- 243:     /// @return The number of builds of this release.
+ 243:     /// @notice The hash of the version tag obtained from the packed, bytes-encoded release and build number.

- 248:     /// @notice The hash of the version tag obtained from the packed, bytes-encoded release and build number.
+ 248:     /// @param _tag The version tag.

- 249:     /// @param _tag The version tag.
+ 249:     /// @return The version tag hash.

- 250:     /// @return The version tag hash.
+ 250:     /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).

- 255:     /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).
+ 255:     /// @dev The caller must have the `UPGRADE_REPO_PERMISSION_ID` permission.

- 256:     /// @dev The caller must have the `UPGRADE_REPO_PERMISSION_ID` permission.
+ 256:     /// @notice Checks if this or the parent contract supports an interface by its ID.

- 261:     /// @notice Checks if this or the parent contract supports an interface by its ID.
+ 261:     /// @param _interfaceId The ID of the interface.

- 262:     /// @param _interfaceId The ID of the interface.
+ 262:     /// @return Returns `true` if the interface is supported.

263:     /// @return Returns `true` if the interface is supported.

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepoFactory.sol

- 12: /// @notice This contract creates `PluginRepo` proxies and registers them on an `PluginRepoRegistry` contract.
+ 12: /// @notice This contract creates `PluginRepo` proxies and registers them on a `PluginRepoRegistry` contract.

- 17:     /// @notice The address of the `PluginRepo` base contract.
+ 17:     /// @notice The address of the `PluginRepo` base contract to proxy to.

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol

- 13: /// @notice This contract maintains an address-based registery of plugin repositories in the Aragon App DAO framework.
+ 13: /// @notice This contract maintains an address-based registry of plugin repositories in the Aragon App DAO framework.

- 19:     /// @notice The ENS subdomain registrar registering the PluginRepo subdomains.
+ 19:     /// @notice The ENS subdomain registrar that registers the PluginRepo subdomains.

Link to code

File: packages/contracts/src/framework/plugin/setup/IPluginSetup.sol

- 13:     /// @param helpers The address array of helpers (contracts or EOAs) associated with this plugin version after the installation or update.
+ 13:     /// @param helpers The address array of helpers (contracts or EOAs) associated with this plugin version after the installation or update. The helpers are not necessarily the same as the plugin implementation.

- 22:     /// @param currentHelpers The address array of all current helpers (contracts or EOAs) associated with the plugin to update from.
+ 22:     /// @param currentHelpers The address array of all current helpers (contracts or EOAs) associated with the plugin to update from. The helpers are not necessarily the same as the plugin implementation.

- 43:     /// @param _payload The relevant data necessary for the `prepareUpdate`. see above.
+ 43:     /// @param _payload The relevant data necessary for the `prepareUpdate`. See above.

- 54:     /// @param _payload The relevant data necessary for the `prepareUninstallation`. see above.
+ 54:     /// @param _payload The relevant data necessary for the `prepareUninstallation`. See above.

Link to code

File: packages/contracts/src/framework/plugin/setup/PluginSetupProcessor.sol

- 154:     /// @notice Thrown if a plugin setup was already prepared inidcated by the prepared setup ID.
+ 154:     /// @notice Thrown if a plugin setup was already prepared indicated by the prepared setup ID.

- 548:     /// @param _dao The address of the installing DAO.
+ 548:     /// @param _dao The address of the uninstalling DAO.

- 609:     /// @param _dao The address of the installing DAO.
+ 609:     /// @param _dao The address of the uninstalling DAO.

Link to code

File: packages/contracts/src/framework/plugin/setup/PluginSetupProcessorHelpers.sol

- 9: /// @notice The struct containin a reference to a plugin setup by specifying the containing plugin repository and the associated version tag.
+ 9: /// @notice The struct containing a reference to a plugin setup by specifying the containing plugin repository and the associated version tag.

- 40: /// @param _data The bytes-encoded initialize data for the upgrade that is returned by `prepareUpdate`.
+ 40: /// @param _data The bytes-encoded initialization data for the upgrade that is returned by `prepareUpdate`.

Link to code

File: packages/contracts/src/framework/utils/InterfaceBasedRegistry.sol

- 24:     /// @notice The mapping containing the registry entries returning true for registererd contract addresses.
+ 24:     /// @notice The mapping containing the registry entries returning true for registered contract addresses.

- 35:     /// @notice Thrown if the contract do not support ERC165.
+ 35:     /// @notice Thrown if the contract does not support ERC165.

Link to code

File: packages/contracts/src/framework/utils/TokenFactory.sol

- 74:     /// @param _tokenConfig The token configuration struct containing the name, and symbol of the token to be create, but also an address. For `address(0)`, a new governance token is created. For any other address pointing to an [ERC-20](https://eips.ethereum.org/EIPS/eip-20)-compatible contract, a wrapped governance token is created.
+ 74:     /// @param _tokenConfig The token configuration struct containing the name, and symbol of the token to be created, but also an address. For `address(0)`, a new governance token is created. For any other address pointing to an [ERC-20](https://eips.ethereum.org/EIPS/eip-20)-compatible contract, a wrapped governance token is created.

- 133:         // Grant the managing DAO permission to directly mint tokens to an receiving address.
+ 133:         // Grant the managing DAO permission to directly mint tokens to a receiving address.

Link to code

File: packages/contracts/src/framework/utils/ens/ENSMigration.sol

- 3: // to compile the contracts and make their artifacts available in our tests.
+ 3: // It compiles the contracts and makes their artifacts available in our tests.

Link to code

File: packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol

- 72:     /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).
+ 72:     /// @notice Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).

- 110:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
+ 110:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).

Link to code

File: packages/contracts/src/plugins/counter-example/MultiplyHelper.sol

- 15:     /// @param _a The number to multiply the coun with.
+ 15:     /// @param _a The number to multiply the count with.

Link to code

File: packages/contracts/src/plugins/counter-example/v1/CounterV1.sol

- 16:     /// @notice A counter varaible.
+ 16:     /// @notice A counter variable.

- 25:     /// @param _count The inital value of the counter.
+ 25:     /// @param _count The initial value of the counter.

- 38:     /// @param _a The number to multiply the coun with.
+ 38:     /// @param _a The number to multiply the count with.

Link to code

File: packages/contracts/src/plugins/counter-example/v1/CounterV1PluginSetup.sol

- 13: /// @title CounterV1PluginSetup
+ 13: /// @title CounterV1Plugin

- 15: /// @notice The setup contract of the `CounterV1` plugin.
+ 15: /// @notice The contract of the `CounterV1` plugin.

Link to code

File: packages/contracts/src/plugins/counter-example/v2/CounterV2PluginSetup.sol

- 23:     // MultiplyHelper doesn't change. so dev decides to pass the old one.
+ 23:     // MultiplyHelper doesn't change, so the dev decides to pass the old one.

- 131:         // if another helper is deployed, put it inside activeHelpers + put old ones as well.
+ 131:         // if another helper is deployed, put it inside activeHelpers and put old ones as well.

Link to code

File: packages/contracts/src/plugins/governance/admin/Admin.sol

- 14: /// @notice The admin governance plugin giving execution permission on the DAO to a single address.
+ 14: /// @notice The admin governance plugin gives execution permission on the DAO to a single address.

- 22:     /// @notice The ID of the permission required to call the `executeProposal` function.
+ 22:     /// @notice The ID of the permission required to call the `executeProposal` function is 0x1.

Link to code

File: packages/contracts/src/plugins/governance/admin/AdminSetup.sol

- 19:     /// @notice The address of `Admin` plugin logic contract to be cloned.
+ 19:     /// @notice The address of the `Admin` plugin logic contract to be cloned.

- 26:     /// @notice The constructor setting the `Admin` implementation contract to clone from.
+ 26:     /// @notice The constructor sets the `Admin` implementation contract to clone from.

- 36:         // Decode `_data` to extract the params needed for cloning and initializing `Admin` plugin.
+ 36:         // Decode `_data` to extract the params needed for cloning and initializing the `Admin` plugin.

- 53:         // Grant `ADMIN_EXECUTE_PERMISSION` of the Plugin to the admin.
+ 53:         // Grant `ADMIN_EXECUTE_PERMISSION` of the plugin to the admin.

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/IMajorityVoting.sol

- 13:     /// @param None The default option state of a voter indicating the absence of from the vote. This option neither influences support nor participation.
+ 13:     /// @param None The default option state of a voter indicating the absence from the vote. This option neither influences support nor participation.

- 56:     /// @return Returns `true` if the participation is greater than the minimum particpation and `false` otherwise.
+ 56:     /// @return Returns `true` if the participation is greater than the minimum participation and `false` otherwise.

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/MajorityVotingBase.sol

- 109:     /// @param VoteReplacment In vote replacement mode, voters can change their vote multiple times and only the latest vote option is tallied.
+ 109:     /// @param VoteReplacement In vote replacement mode, voters can change their vote multiple times and only the latest vote option is tallied.

- 367:     /// @notice Returns the minimum voting power required to create a proposa stored in the voting settings.
+ 367:     /// @notice Returns the minimum voting power required to create a proposal stored in the voting settings.

- 593:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
+ 593:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/addresslist/AddresslistVotingSetup.sol

- 19:     /// @notice The contract constructor, that deployes the `AddresslistVoting` plugin logic contract.
+ 19:     /// @notice The contract constructor, that deploys the `AddresslistVoting` plugin logic contract.

- 49:         // Grant the list of prmissions of the plugin to the DAO.
+ 49:         // Grant the list of permissions of the plugin to the DAO.

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol

- 16: /// @notice The majority voting implementation using an [OpenZepplin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible governance token.
+ 16: /// @notice The majority voting implementation using an [OpenZeppelin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible governance token.

- 25:     /// @notice An [OpenZepplin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible contract referencing the token being used for voting.
+ 25:     /// @notice An [OpenZeppelin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible contract referencing the token being used for voting.

- 210:         // The voter has already voted but vote replacment is not allowed.
+ 210:         // The voter has already voted but vote replacement is not allowed.

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/token/TokenVotingSetup.sol

- 56:     /// @notice Thrown if passed helpers array is of worng length.
+ 56:     /// @notice Thrown if passed helpers array is of wrong length.

- 60:     /// @notice The contract constructor, that deployes the bases.
+ 60:     /// @notice The contract constructor, that deploys the bases.

- 155:         // Grant the list of prmissions of the plugin to the DAO.
+ 155:         // Grant the list of permissions of the plugin to the DAO.

Link to code

File: packages/contracts/src/plugins/governance/multisig/IMultisig.sol

- 15:     /// @notice Removes existing members from the address list. Previously, it checks if the new addresslist length is at least as long as the minimum approvals parameter requires. Note that `minApprovals` is must be at least 1 so the address list cannot become empty.
+ 15:     /// @notice Removes existing members from the address list. Previously, it checks if the new address list length is at least as long as the minimum approvals parameter requires. Note that `minApprovals` must be at least 1 so the address list cannot become empty.

Link to code

File: packages/contracts/src/plugins/governance/multisig/Multisig.sol

- 84:     /// @notice Thrown if a approver is not allowed to cast an approve. This can be because the proposal
+ 84:     /// @notice Thrown if an approver is not allowed to cast an approve. This can be because the proposal

- 111:     /// @notice Emitted when an proposal is approve by an approver.
+ 111:     /// @notice Emitted when a proposal is approved by an approver.

Link to code

File: packages/contracts/src/plugins/governance/multisig/MultisigSetup.sol

- 18:     /// @notice The contract constructor, that deployes the `Multisig` plugin logic contract.
+ 18:     /// @notice The contract constructor, that deploys the `Multisig` plugin logic contract.

- 45:         // Grant the list of prmissions of the plugin to the DAO.
+ 45:         // Grant the list of permissions of the plugin to the DAO.

Link to code

File: packages/contracts/src/plugins/token/IMerkleDistributor.sol

- 13:     /// @param to The address to which the tokens are send.
+ 13:     /// @param to The address to which the tokens are sent.

- 17:     /// @notice The [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token to be distributed.
+ 17:     /// @notice The [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token that is distributed.

Link to code

File: packages/contracts/src/plugins/token/IMerkleMinter.sol

- 32:     /// @notice changes the base distributor address
+ 32:     /// @notice Changes the base distributor address.

- 33:     /// @param _distributorBase the address of base distributor
+ 33:     /// @param _distributorBase The address of the base distributor.

Link to code

File: packages/contracts/src/plugins/token/MerkleDistributor.sol

- 28:     /// @notice A packed array of booleans containing the information who claimed.
+ 28:     /// @notice A packed array of booleans containing the information of who claimed.

- 128:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
+ 128:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).

Link to code

File: packages/contracts/src/plugins/token/MerkleMinter.sol

- 97:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
+ 97:     /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).

Link to code

File: packages/contracts/src/plugins/utils/Addresslist.sol

- 11: /// @notice The majority voting implementation using an list of member addresses.
+ 11: /// @notice The majority voting implementation using a list of member addresses.

Link to code

File: packages/contracts/src/plugins/utils/Ratio.sol

- 8: /// @notice Thrown if a ratio value exceeds the maximal value of `10**6`.
+ 8: /// @notice Throws if a ratio value exceeds the maximal value of `10**6`.

- 13: /// @notice Applies a ratio to a value and ceils the remainder.
+ 13: /// @notice Applies a ratio to a value and rounds up the remainder.

- 26:     // Check if ceiling is needed
+ 26:     // Check if rounding up is needed

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceERC20.sol

- 47:     /// @param _symbol The symbol fo the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) governance token.
+ 47:     /// @param _symbol The symbol of the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) governance token.

- 61:     /// @param _symbol The symbol fo the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) governance token.
+ 61:     /// @param _symbol The symbol of the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) governance token.

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceWrappedERC20.sol

- 21: /// @notice Wraps an existing [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token by inheriting from `ERC20WrapperUpgradeable` and allows to use it for voting by inheriting from `ERC20VotesUpgradeable`. The latter is compatible with [OpenZepplin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) interface.
+ 21: /// @notice Wraps an existing [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token by inheriting from `ERC20WrapperUpgradeable` and allows to use it for voting by inheriting from `ERC20VotesUpgradeable`. The latter is compatible with the [OpenZeppelin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) interface.

- 25: /// To get the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens back, the owner of the wrapped tokens can call `withdrawFor`, which  burns the wrapped tokens [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens and safely transfers the underlying tokens back to the owner.
+ 25: /// To get the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens back, the owner of the wrapped tokens can call `withdrawFor`, which  burns the wrapped [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens and safely transfers the underlying tokens back to the owner.

Link to code

File: packages/contracts/src/token/ERC20/governance/IGovernanceWrappedERC20.sol

- 17:     /// @param amount The amount of underlying tokens to be withdrawn.
+ 17:     /// @param amount The amount of underlying tokens to withdraw.

Link to code

File: packages/contracts/src/utils/Proxy.sol

- 11: /// @dev Initializes the upgradeable proxy with an initial implementation specified by _logic. If _data is non-empty, it’s used as data in a delegate call to _logic. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor (see [OpenZepplin ERC1967Proxy-constructor](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Proxy-constructor-address-bytes-)).
+ 11: /// @dev Initializes the upgradeable proxy with an initial implementation specified by _logic. If _data is non-empty, it’s used as data in a delegate call to _logic. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor (see [OpenZeppelin ERC1967Proxy-constructor](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Proxy-constructor-address-bytes-)).

Link to code

File: packages/contracts/src/utils/UncheckedMath.sol

- 15: /// @notice Add two unsigned integers without checking the result for overflow errors (using safe math).
+ 15: /// @notice Adds two unsigned integers without checking the result for overflow errors (using safe math)

Link to code

Low Issues

Issue Instances
L-1 abi.encodePacked() should not be used with dynamic types when passing the result to a hash function such as keccak256() 4
L-2 Empty Function Body - Consider commenting why 11
L-3 Initializers could be front-run 71

[L-1] 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

Instances (4):

File: packages/contracts/src/core/permission/PermissionManager.sol

347:         return keccak256(abi.encodePacked("PERMISSION", _who, _where, _permissionId));

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepo.sol

252:         return keccak256(abi.encodePacked(_tag.release, _tag.build));

Link to code

File: packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol

86:         bytes32 subnode = keccak256(abi.encodePacked(node, _label));

Link to code

File: packages/contracts/src/plugins/token/MerkleDistributor.sol

105:         bytes32 node = keccak256(abi.encodePacked(_index, _to, _amount));

Link to code

[L-2] Empty Function Body - Consider commenting why

Instances (11):

File: packages/contracts/src/core/dao/DAO.sol

136:     function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {}

Link to code

File: packages/contracts/src/core/permission/PermissionManager.sol

320:         } catch {}

Link to code

File: packages/contracts/src/core/plugin/Plugin.sol

17:     constructor(IDAO _dao) DaoAuthorizable(_dao) {}

Link to code

File: packages/contracts/src/core/plugin/PluginUUPSUpgradeable.sol

63:     ) internal virtual override auth(UPGRADE_PLUGIN_PERMISSION_ID) {}

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepo.sol

259:     ) internal virtual override auth(UPGRADE_REPO_PERMISSION_ID) {}

Link to code

File: packages/contracts/src/framework/plugin/setup/PluginSetup.sol

27:     {}

Link to code

File: packages/contracts/src/framework/plugin/setup/PluginSetupProcessor.sol

672:             {} catch Error(string memory reason) {

682:             try PluginUUPSUpgradeable(_proxy).upgradeTo(_implementation) {} catch Error(

Link to code

File: packages/contracts/src/framework/utils/InterfaceBasedRegistry.sol

56:     ) internal virtual override auth(UPGRADE_REGISTRY_PERMISSION_ID) {}

Link to code

File: packages/contracts/src/framework/utils/ens/ENSMigration.sol

10: contract Dummy {}

Link to code

File: packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol

76:     ) internal virtual override auth(UPGRADE_REGISTRAR_PERMISSION_ID) {}

Link to code

[L-3] Initializers could be front-run

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

Instances (71):

File: packages/contracts/src/core/dao/DAO.sol

104:     function initialize(

109:     ) external initializer {

118:         __PermissionManager_init(_initialOwner);

Link to code

File: packages/contracts/src/core/permission/PermissionManager.sol

95:     function __PermissionManager_init(address _initialOwner) internal onlyInitializing {

Link to code

File: packages/contracts/src/core/plugin/PluginCloneable.sol

22:     function __PluginCloneable_init(IDAO _dao) internal virtual onlyInitializing {

23:         __DaoAuthorizableUpgradeable_init(_dao);

Link to code

File: packages/contracts/src/core/plugin/PluginUUPSUpgradeable.sol

39:     function __PluginUUPSUpgradeable_init(IDAO _dao) internal virtual onlyInitializing {

40:         __DaoAuthorizableUpgradeable_init(_dao);

Link to code

File: packages/contracts/src/core/plugin/dao-authorizable/DaoAuthorizableUpgradeable.sol

20:     function __DaoAuthorizableUpgradeable_init(IDAO _dao) internal onlyInitializing {

Link to code

File: packages/contracts/src/framework/dao/DAOFactory.sol

146:         dao.initialize(

Link to code

File: packages/contracts/src/framework/dao/DAORegistry.sol

37:     function initialize(

40:     ) external initializer {

41:         __InterfaceBasedRegistry_init(_managingDao, type(IDAO).interfaceId);

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepo.sol

120:     function initialize(address initialOwner) external initializer {

120:     function initialize(address initialOwner) external initializer {

121:         __PermissionManager_init(initialOwner);

Link to code

File: packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol

41:     function initialize(IDAO _dao, ENSSubdomainRegistrar _subdomainRegistrar) external initializer {

41:     function initialize(IDAO _dao, ENSSubdomainRegistrar _subdomainRegistrar) external initializer {

43:         __InterfaceBasedRegistry_init(_dao, pluginRepoInterfaceId);

Link to code

File: packages/contracts/src/framework/utils/InterfaceBasedRegistry.sol

43:     function __InterfaceBasedRegistry_init(

47:         __DaoAuthorizableUpgradeable_init(_managingDao);

Link to code

File: packages/contracts/src/framework/utils/TokenFactory.sol

100:             GovernanceWrappedERC20(token).initialize(

112:         GovernanceERC20(token).initialize(

121:         MerkleMinter(merkleMinter).initialize(

Link to code

File: packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol

57:     function initialize(IDAO _managingDao, ENS _ens, bytes32 _node) external initializer {

57:     function initialize(IDAO _managingDao, ENS _ens, bytes32 _node) external initializer {

58:         __DaoAuthorizableUpgradeable_init(_managingDao);

Link to code

File: packages/contracts/src/plugins/counter-example/v1/CounterV1.sol

26:     function initialize(

30:     ) external initializer {

31:         __PluginUUPSUpgradeable_init(_dao);

Link to code

File: packages/contracts/src/plugins/counter-example/v1/CounterV1PluginSetup.sol

48:             bytes4(keccak256("initialize(address,address,uint256)")),

Link to code

File: packages/contracts/src/plugins/counter-example/v2/CounterV2.sol

32:     function initialize(

37:     ) external reinitializer(2) {

38:         __PluginUUPSUpgradeable_init(_dao);

52:     function setNewVariable(uint256 _newVariable) external reinitializer(2) {

Link to code

File: packages/contracts/src/plugins/counter-example/v2/CounterV2PluginSetup.sol

49:             bytes4(keccak256("initialize(address,address,uint256)")),

Link to code

File: packages/contracts/src/plugins/governance/admin/Admin.sol

29:     function initialize(IDAO _dao) external initializer {

29:     function initialize(IDAO _dao) external initializer {

30:         __PluginCloneable_init(_dao);

Link to code

File: packages/contracts/src/plugins/governance/admin/AdminSetup.sol

47:         Admin(plugin).initialize(IDAO(_dao));

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/MajorityVotingBase.sol

238:     function __MajorityVotingBase_init(

242:         __PluginUUPSUpgradeable_init(_dao);

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/addresslist/AddresslistVoting.sol

34:     function initialize(

38:     ) external initializer {

39:         __MajorityVotingBase_init(_dao, _votingSettings);

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/token/TokenVoting.sol

36:     function initialize(

40:     ) external initializer {

41:         __MajorityVotingBase_init(_dao, _votingSettings);

Link to code

File: packages/contracts/src/plugins/governance/majority-voting/token/TokenVotingSetup.sol

123:                 GovernanceWrappedERC20(token).initialize(

132:             GovernanceERC20(token).initialize(

Link to code

File: packages/contracts/src/plugins/governance/multisig/Multisig.sol

125:     function initialize(

129:     ) external initializer {

130:         __PluginUUPSUpgradeable_init(_dao);

Link to code

File: packages/contracts/src/plugins/token/MerkleDistributor.sol

46:     function initialize(

50:     ) external initializer {

51:         __PluginUUPSUpgradeable_init(_dao);

Link to code

File: packages/contracts/src/plugins/token/MerkleMinter.sol

41:     function initialize(

45:     ) external initializer {

46:         __PluginUUPSUpgradeable_init(_dao);

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceERC20.sol

55:         initialize(_dao, _name, _symbol, _mintSettings);

63:     function initialize(

68:     ) public initializer {

77:         __ERC20_init(_name, _symbol);

78:         __ERC20Permit_init(_name);

79:         __DaoAuthorizableUpgradeable_init(_dao);

Link to code

File: packages/contracts/src/token/ERC20/governance/GovernanceWrappedERC20.sol

39:         initialize(_token, _name, _symbol);

46:     function initialize(

50:     ) public initializer {

51:         __ERC20_init(_name, _symbol);

52:         __ERC20Permit_init(_name);

53:         __ERC20Wrapper_init(_token);

Link to code

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