Aragon Protocol contest - 0xAgro's results

The most user-friendly tech stack to launch your DAO.

General Information

Platform: Code4rena

Start Date: 03/03/2023

Pot Size: $90,500 USDC

Total HM: 4

Participants: 42

Period: 7 days

Judge: 0xean

Total Solo HM: 2

Id: 219

League: ETH

Aragon Protocol

Findings Distribution

Researcher Performance

Rank: 15/42

Findings: 1

Award: $720.35

QA:
grade-a

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

720.3467 USDC - $720.35

Labels

bug
grade-a
QA (Quality Assurance)
sponsor acknowledged
Q-12

External Links

QA Report

Finding Summary

Low Severity

  1. Unchecked Cast May Overflow
  2. Low Test Coverage
  3. Draft EIP Used

Non-Critical

  1. Contracts Missing @title Tag
  2. Inconsistent Comment Initial Spacing
  3. Inconsistent Named Returns
  4. bytes.concat() Can Be Used Over abi.encodePacked()
  5. Explicit Function Scope Not Used
  6. Space Between License and Pragma
  7. Extra Spaces In License Identifier
  8. Inconsistent Comment Capitalization
  9. Inconsistent Trailing Period
  10. Only Single Line NatSpec Comments Used
  11. Named Returns Not Returning Named Variable
  12. ERC20 Token Recovery
  13. Constants Used Multiple Times

Style Guide Violations

  1. Maximum Line Length
  2. Order of Functions
  3. Whitespace in Expressions
  4. Function Declaration Style
  5. Order of Layout

Low Severity

1. Unchecked Cast May Overflow

As of Solidity 0.8 overflows are handled automatically; however, not for casting. For example uint32(4294967300) will result in 4 without reversion. Consider using a SafeCast library (which is used in other parts of the codebase).

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

17:	uint8 char = uint8(nameBytes[i]);

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

175:	uint16 newAddresslistLength = uint16(addresslistLength() - _members.length);
414:	uint16 addresslistLength_ = uint16(addresslistLength());

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

210:	uint16 latestBuild = uint16(buildsPerRelease[_release]);

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

192:	if (!hasBit(_allowFailureMap, uint8(i))) {
198:	failureMap = flipBit(failureMap, uint8(i));

2. Low Test Coverage

The Scoping Details states that the test coverage is 60%. The code coverage of the files in scope is not 100%. Consider a test coverage of 100%.

3. Draft EIP Used

ERC4824 is used in the codebase. EIP 4824 is in draft and could change, thus possibly impacting Aragon in the future. EIP 4824 states:

This EIP is not yet recommended for general use or implementation, as it is subject to normative (breaking) changes.

Non-Critical

1. Contracts Missing @title Tag

11 out of 62 of the contracts in scope are missing a @title tag. Given that 51 contracts all have a @title tag, consider adding one per the 11 remaining contracts.

Proxy.sol, UncheckedMath.sol, RegistryUtils.sol, ENSMigration.sol, PluginSetupProcessorHelpers.sol, Ratio.sol, IMerkleMinter.sol, IMerkleDistributor.sol, BitMap.sol, auth.sol, and IGovernanceWrappedERC20.sol are missing a @title tag.

2. Inconsistent Comment Initial Spacing

Some comments have an initial space after // or /// while others do not. It is best for code clearity to keep a consistent style. All contracts in the codebase have initial space comments. CounterV2.sol, and CounterV1.sol have some non-initial space comments (//dao.execute(...)).

3. Inconsistent Named Returns

Some functions use named returns and others do not. It is best for code clearity to keep a consistent style.

  1. The following contracts only have named returns (EX. returns(uint256 foo)): DAOFactory.sol, PluginSetupProcessor.sol, and Ratio.sol.
  2. The following contracts only have non-named returns (EX. returns(uint256)): Proxy.sol, UncheckedMath.sol, TokenFactory.sol, RegistryUtils.sol, Admin.sol, PluginRepo.sol, PluginSetupProcessorHelpers.sol, MultiplyHelper.sol, Addresslist.sol, CounterV2.sol, CounterV1.sol, MerkleDistributor.sol, PermissionManager.sol, CallbackHandler.sol, BitMap.sol, PluginUUPSUpgradeable.sol, DaoAuthorizableUpgradeable.sol, DaoAuthorizable.sol, Plugin.sol, PluginCloneable.sol, GovernanceWrappedERC20.sol, and GovernanceERC20.sol.
  3. The following contracts have both: MajorityVotingBase.sol, AddresslistVotingSetup.sol, AddresslistVoting.sol, TokenVoting.sol, TokenVotingSetup.sol, MultisigSetup.sol, Multisig.sol, AdminSetup.sol, PluginRepoFactory.sol, PluginSetup.sol, CounterV2PluginSetup.sol, CounterV1PluginSetup.sol, MerkleMinter.sol, DAO.sol, ProposalUpgradeable.sol, and Proposal.sol.

4. bytes.concat() Can Be Used Over abi.encodePacked()

Consider using bytes.concat() instead of abi.encodePacked() in contracts with Solidity version >= 0.8.4.

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

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

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

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

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

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

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

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

5. Explicit Function Scope Not Used

Function scopes should be explicit and not left out if public (the default). The following are not explicitly deemed public:

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

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

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

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

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

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

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

6. Space Between License and Pragma

All contracts in scope have a space between the license statement and pragma (ex). Although it does not void the Solidity Style Guide, all example contracts in the Style Guide do not have a space between the license statement and pragma (ex). This format can also be seen throughout the Solidy Documentation (ex). Consider removing the needless space.

7. Extra Spaces In License Identifier

In PluginRepo.sol there are 3 extra spaces in the license identifier. Contracts like GovernanceERC20.sol do not have this extra space. Consider removing the extra spaces in PluginRepo.sol.

Example

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

1:	// SPDX-License-Identifier:    AGPL-3.0-or-later

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

1:	// SPDX-License-Identifier: AGPL-3.0-or-later

8. Inconsistent Comment Capitalization

There is an inconsistency in the capitalization of comments. For example, this line is not capitilized while - like most - this line is. Consider capitilizing all comments.

9. Inconsistent Trailing Period

Some comments like this have a trailing . but other lines like this do not.

Consider sticking to a single comment style for a less distracting developer experience.

10. Only Single Line NatSpec Comments Used

All NatSpec comments in the codebase use single line NatSpec comments through /// like so:

19:	/// @title GovernanceWrappedERC20
20:	/// @author Aragon Association
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.
22:	/// The contract also supports meta transactions. To use an `amount` of underlying tokens for voting, the token owner has to
23:	/// 1. call `approve` for the tokens to be used by this contract
24:	/// 2. call `depositFor` to wrap them, which safely transfers the underlying [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens to the contract and mints wrapped [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens.
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.
26:	/// @dev This contract intentionally has no public mint functionality because this is the responsibility of the underlying [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token contract.

As described in the Solidity Documentation multi-line comments may use the /** format. The use of /// for multi-line is allowed by Solidity standards; however, for comments like this it is far easier to read using the mulit-line /** style. Consider using the mulit-line /** NstSpec style for long NatSpec comments.

11. Named Returns Not Returning Named Variable

Using named returns may help developers understand what is being returned, but this should be in a @return tag. There is no need to confuse developers. The following functions have named returned but still return one or more variables.

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

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

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

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

12. ERC20 Token Recovery

Consider adding a recovery function for Tokens that are accidently sent to the core contracts of the protocol.

13. Constants Used Multiple Times

There is a relatively large amount of constants used in the codebase (seen here for example). In some cases like this and this the same constant is referenced in different contracts. Consider addings a constants contract to hold all constants used in Aragon.

Style Guide Violations

1. Maximum Line Length

Lines with greater length than 120 characters are used. The Solidity Style Guide suggests that all lines should be 120 characters or less in width.

The following lines are longer than 120 characters, it is suggested to shorten these lines:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2. Order of Functions

The Solidity Style Guide suggests the following function order: constructor, receive function (if exists), fallback function (if exists), external, public, internal, private.

The following contracts are not compliant (examples are only to prove the functions are out of order NOT a full description):

3. Whitespace in Expressions

The Solidity Style Guide recommends to "[a]void extraneous whitespace [i]mmediately inside parenthesis, brackets or braces, with the exception of single line function declarations". The Style Guide also recommends against spaces before semicolons. Consider removing spaces before semicolons.

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

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

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

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

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

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

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

674:	} catch (bytes memory ) {
686:	} catch (bytes memory ) {

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

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

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

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

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

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

4. Function Declaration Style

The Solidity Style Guide states that "[f]or short function declarations, it is recommended for the opening brace of the function body to be kept on the same line as the function declaration". It is not clear what length is exactly meant by "short" or "long". The maximum line length of 120 characters may be an indication, and in that case any expanded function declaration under 120 characters should be on a single line.

The following functions in their respective contracts are not compliant by this standard:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

5. Order of Layout

The Solidity Style Guide suggests the following contract layout order: Type declarations, State variables, Events, Modifiers, Functions.

The following contracts are not compliant (examples are only to prove the layout are out of order NOT a full description):

The following are also techically not compliant; however, understandably use a __gap for reserved space (compliant otherwise):

#0 - c4-judge

2023-03-12T16:30:30Z

0xean marked the issue as grade-a

#1 - novaknole20

2023-03-22T13:13:16Z

  1. Unchecked Cast May Overflow

This is fine in each place.

  1. Explicit Function Scope Not Used

These are file level functions (aka free functions) for which one cannot define visiblity.

#2 - c4-sponsor

2023-03-22T13:13:22Z

novaknole20 marked the issue as sponsor acknowledged

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter