Open c4-bot-1 opened 8 months ago
Picodes marked the issue as satisfactory
Picodes marked the issue as selected for report
Although these three issues are described together here, I want to remind that they should be listed as two different medium issues:
markBallotAsFinalized()
doesn't check if the ballot to be removed is living or not.can be finalized
ballot could be removed accidentally or intentionally when time exceeds ballotMaximumEndTime
.The root causes of them are different, and the consequences are also different
It seems from sponsor's comments in #94 that issue 3
is to be considered invalid?
Checking that the ballot has not already been finalized is definitely important. Thank you!
Fixed in: bea938fb1c667be81ce4ea135b758626a756927c
Allowing ballots to be manually ended even if they could be approved is valid. In a governance attack there may be spammed ballots (like send SALT which can only be now executed once a week). It can be useful for those spammed ballots to be removed.
othernet-global (sponsor) confirmed
@piken Yes indeed I consider point 3 to be invalid as discussed in #94
Lines of code
https://github.com/othernet-global/salty-io/blob/758349850a994c305a0ab9a151d00e738a5a45a0/src/dao/DAO.sol#L271-L279 https://github.com/othernet-global/salty-io/blob/758349850a994c305a0ab9a151d00e738a5a45a0/src/dao/Proposals.sol#L131-L153
Vulnerability details
Comments
In the original implementation, a ballot cannot be closed or canceled without meeting the required quorum, even if the
ballotMinimumEndTime
has passed.Mitigation
commit 7583498 The mitigation introduced a variable
ballotMaximumDuration
for ballot and a functionDAO#manuallyRemoveBallot()
. Whenever a ballot is expired, it can be removed by any one.Impact
Three new issues were produced due to missing status checks:
Proof of Concept
DAO#manuallyRemoveBallot()
DAO#manuallyRemoveBallot()
to remove ballotA again._userHasActiveProposal[Alice]
was reset tofalse
DAO#manuallyRemoveBallot()
DAO#manuallyRemoveBallot(A1)
to remove ballot again,openBallotsByName[ballotA]
was deletedballotMinimumDuration
as 10 days andballotMaximumDuration
as 30 daysrequiredQuorum
requiredQuorum
threshold.DAO#manuallyRemoveBallot()
to remove the vote.POC of Issue 1 & 2: Copy below codes to DAO.t.sol and run
COVERAGE="yes" NETWORK="sep" forge test -vv --rpc-url RPC_URL --match-test testManualRemovalBallotIssue1And2&2
POC of Issue 3: Copy below codes to DAO.t.sol and run
COVERAGE="yes" NETWORK="sep" forge test -vv --rpc-url RPC_URL --match-test testManualRemovalBallotIssue3
Tools Used
Manual review
Recommended Mitigation Steps
Check if the ballot is living before removing it:
Any ballot that can be finalized should not be removable:
Assessed type
Invalid Validation