Open c4-bot-9 opened 9 months ago
Picodes marked the issue as primary issue
othernet-global (sponsor) disputed
There are automatic confirmation votes associated with the setContract and websiteUpdate proposals. When those proposals succeed a mandatory confirmation vote is started to prevent last minute surprise votes.
I do agree with the report but do not see how it fulfills the definition of Medium severity under C4's rules. To me, it's a design choice that could lead to vote results switching unexpectedly.
Picodes changed the severity to QA (Quality Assurance)
Lines of code
https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/dao/Proposals.sol#L276-L290
Vulnerability details
Impact
The DAO is in control of very powerful actions, like changing price feeds used for borrowing and liquidations, changing the access manager, adding whitelisted tokens, and sending SALT from the DAO to any user, among other actions.
Users with enough staking (and therefore voting power) can vote on the very last possible block, flipping a ballot decision.
They can even signal the opposite vote during the whole course of the voting, and change it on the last minute.
Votes on the last minute have the same voting power as the ones casted before.
An adversary can take advantage of this. For example, they can propose malicious ballots with an account, and have another one with more voting power. The one with the most voting power can signal an "against" vote for the whole ballot duration to persuade other voters that the proposal will be rejected, and flip the vote in the last minute if they see they can win.
It is important to note that there is no penalization for creating malicious ballots over and over, and an adversary only needs to win one ballot to make some damage to the DAO and the protocol.
Note: This Impact fits into the Attack Ideas: "Any issue that would prevent the DAO from functioning correctly."
Vulnerability Details
When casting a vote, the
userVotingPower
represents 100% of the user share for the staked SALT pool, with no cap, nor affected by the time the vote was cast:Proposals.sol#L276-L290
It can also be seen that a user can first vote for an option, and switch to the opposite one on the last minute, without any penalization.
Proof of Concept
src/dao/tests/Proposals.t.sol
COVERAGE="no" NETWORK="sep" forge test -vv --rpc-url https://1rpc.io/sepolia --mt "testSameVotingPowerAtEndOfBallot"
Recommended Mitigation Steps
There are multiple ways to mitigate this. One easy way could be to linearly or exponentially decrease the voting power on the last lap of the voting phase. Other more sophisticated options are exposed on the Lido Proposal for "last minute vote mitigation", or the Time-weighted voting by Curve.
Assessed type
Governance