Submitted by Madalad, also found by sin1st3r__, adriro, Emmanuel, 0xbepresent, evmboi32, Shaheen, 3docSec, klau5 (1, 2), ast3ros, pontifex, HChang26, bart1e, P12473, and rvierdiiev
After a proposal passes the vote threshold, there is a delay before it can be executed so that hosts get a chance to veto it if they wish. If all hosts voting in favour of the proposal, then this veto period is skipped.
However, a single host can ensure the veto period is skipped even if no other hosts accept the proposal. The veto period is in place to prevent harmful/exploitative proposals from being executed, even if they are passed; therefore, a malicious/compromised host being able to skip the veto period can be seriously harmful to the protocol and its users. The Tornado Cash governance hack from May 2023 is a relevant example, during which the attacker was able to steal around $1 million worth of assets.
This attack has a very low cost and a very high potential impact. If a malicious proposal is crafted in the same way used by the Tornado Cash attacker using hidden CREATE2 and SELFDESTRUCT operations, then it is entirely feasible that it would meet the voting threshold, as many voters may not be savvy enough to spot the red flags.
PartyGovernance#abdicateHost is a function that allows a host to renounce their host privileges, and transfer them to another address.
https://github.com/code-423n4/2023-10-party/blob/main/contracts/party/PartyGovernance.sol#L457
This can be done at any stage in the life cycle of a proposal. This means that a host can accept a proposal, incrementing the numHostsAccepted value for that proposal, then transfer the host status to another wallet that they control (that has non-zero voting power) and accept again, incrementing numHostsAccepted for a second time. This process can be repeated as many times as necessary until numHostsAccepted is equal to the total number of hosts numHosts. Once the proposal reaches the required vote threshold, the veto period will be skipped, despite only one host accepting.
The following foundry test shows the process described above. Copy and paste it into PartyGovernanceTest.t.sol to run.
Utilise snapshots for hosts in a similar way to how votingPower is currently handled, so that accept only increments numHostsAccepted if the caller was a host at proposedTime - 1. This can be achieved under the current architecture in the following way:
Governance
gzeon (judge) commented:
0xble (Party) confirmed
Note: For full discussion, see here.
