Platform: Code4rena
Start Date: 03/08/2023
Pot Size: $90,500 USDC
Total HM: 6
Participants: 36
Period: 7 days
Judge: 0xean
Total Solo HM: 1
Id: 273
League: ETH
Rank: 6/36
Findings: 1
Award: $4,429.19
š Selected for report: 1
š Solo Findings: 0
š Selected for report: AkshaySrivastav
Also found by: MiloTruck
4429.1881 USDC - $4,429.19
The SecurityCouncilMemberRemovalGovernor
contract inherits GovernorUpgradeable
& EIP712Upgradeable
contracts but does not invoke their individual initialzers during its own initialization. Due to which the state of GovernorUpgradeable
& EIP712Upgradeable
contracts remain uninitialized.
contract SecurityCouncilMemberRemovalGovernor is GovernorUpgradeable, GovernorVotesUpgradeable, ... { function initialize( ... ) public initializer { __GovernorSettings_init(_votingDelay, _votingPeriod, _proposalThreshold); __GovernorCountingSimple_init(); __GovernorVotes_init(_token); __ArbitrumGovernorVotesQuorumFraction_init(_quorumNumerator); __GovernorPreventLateQuorum_init(_minPeriodAfterQuorum); __ArbitrumGovernorProposalExpirationUpgradeable_init(_proposalExpirationBlocks); _transferOwnership(_owner); ... } }
abstract contract GovernorUpgradeable is EIP712Upgradeable, ... { function __Governor_init(string memory name_) internal onlyInitializing { __EIP712_init_unchained(name_, version()); __Governor_init_unchained(name_); } function __Governor_init_unchained(string memory name_) internal onlyInitializing { _name = name_; } }
Due to this issue:
GovernorUpgradeable
the _name
storage variable is never initialized and the name()
function returns an empty string.EIP712Upgradeable
the _HASHED_NAME
storage variable is never initialized. This variable is used in the castVoteBySig
& castVoteWithReasonAndParamsBySig
functions of SecurityCouncilMemberRemovalGovernor
.The non-initialization of EIP712Upgradeable
contract breaks the compatibility of SecurityCouncilMemberRemovalGovernor
contract with the EIP712 standard.
It should be noted that the other contracts like SecurityCouncilMemberElectionGovernor
and SecurityCouncilNomineeElectionGovernor
also inherits the GovernorUpgradeable
& EIP712Upgradeable
contracts and initializes them correctly. So the incorrect initialization of SecurityCouncilMemberRemovalGovernor
also breaks the overall code consistency of protocol.
The SecurityCouncilMemberElectionGovernor
and SecurityCouncilNomineeElectionGovernor
contract also force users to do voting only via castVoteWithReasonAndParams
and castVoteWithReasonAndParamsBySig
functions. Hence it can be clearly observed that the protocol wants to utilize voting-by-signature feature, which requires EIP712 compatibility.
This test case was added in test/security-council-mgmt/SecurityCouncilMemberRemovalGovernor.t.sol
and ran using forge test --mt test_audit
.
function test_audit_notInvoking___Governor_init() public { assertEq(scRemovalGov.name(), ""); assertEq(bytes(scRemovalGov.name()).length, 0); }
Foundry
Consider initializing the GovernorUpgradeable
& EIP712Upgradeable
contracts in SecurityCouncilMemberRemovalGovernor.initialize
function.
function initialize( ... ) public initializer { __Governor_init("SecurityCouncilMemberRemovalGovernor"); ... }
Other
#0 - 0xSorryNotSorry
2023-08-12T11:12:19Z
#1 - c4-pre-sort
2023-08-12T11:12:22Z
0xSorryNotSorry marked the issue as low quality report
#2 - c4-judge
2023-08-18T13:43:21Z
0xean marked the issue as unsatisfactory: Out of scope
#3 - akshaysrivastav
2023-08-22T04:33:59Z
Hey @0xean I would like to add more context for this report.
I was aware that this issue has been included in the automated findings but still reported this bug due to following reasons:
Upgradeable contract not initialized
section are false positives.False positives reported in automated report:
SecurityCouncilManager
does not need to invoke __AccessControl_init
as __AccessControl_init
is an empty function.SecurityCouncilMemberElectionGovernor
does not need to invoke __Ownable_init
because the contract wants to provide ownership to a input parameter _owner
while the __Ownable_init
gives ownership to msg.sender
. To achieve that the SecurityCouncilMemberElectionGovernor
invokes the _transferOwnership
function with _owner
parameter in the initializer.SecurityCouncilMemberRemovalGovernor
:
__ArbitrumGovernorProposalExpiration_init
correctly.__Ownable_init
case correctly similar to above explained SecurityCouncilMemberElectionGovernor
case.__Governor_init
, this is the issue reported by me.SecurityCouncilNomineeElectionGovernor
handles the __Ownable_init
case correctly similar to above explained SecurityCouncilMemberElectionGovernor
case.Due to the above explained reasons I separately reported this bug as medium
severity. The bug leads to incompatibility of a protocol contract with EIP712 standard which the contract always wanted to adhere to.
Hope this report can be reviewed again. Thanks.
#4 - MiloTruck
2023-08-22T08:39:45Z
Hi @0xean, would like to add on to what was stated above as my issue #253 is a duplicate.
The C4 docs explicitly states that raising issues from bot reports to a higher severity is fair game, as seen here:
Wardens may use automated tools as a first pass, and build on these findings to identify High and Medium severity issues ("HM issues"). However, submissions based on automated tools will have a higher burden of proof for demonstrating to sponsors a relevant HM exploit path in order to be considered satisfactory.
In my issue, I've demonstrated how the missing __Governor_init()
call results in incorrect signature verification in castVoteBySig()
and castVoteWithReasonAndParamsBySig()
and violates the EIP-712 standard, which in my opinion is deserving of medium severity.
Additionally, as pointed out above, it would have been extremely easy for a sponsor to miss this medium finding amongst all the other false positives in the bot report.
As such, I don't think this finding should be ruled out as OOS as we've demonstrated how it has a greater severity than stated in the bot report and provided additional value to the sponsor.
Would like to hear your opinion as a judge, thanks!
#5 - 0xean
2023-08-22T12:37:50Z
Thanks for the comments. After reviewing, I think raising this to M and awarding this is fair. The bot report is vague on impact and without this being called to the sponsors attention explicitly with a much broader impact, it could go unfixed until a later date.
Will welcome sponsor comments before making a final call ( cc @c4-sponsor )
#6 - c4-judge
2023-08-22T12:38:04Z
0xean marked the issue as satisfactory
#7 - c4-judge
2023-08-22T12:38:10Z
0xean marked the issue as primary issue
#8 - yahgwai
2023-08-22T16:24:37Z
Issue was well written and had correct mitigation I think M seems fair, ty for finding it and pointing it out!
Fix here: https://github.com/ArbitrumFoundation/governance/commit/1a6b66d23f1226e93f0d67c3ed8e9fe1174c178c
#9 - c4-judge
2023-08-23T13:37:06Z
0xean marked the issue as selected for report