Stale `preciousListHash` state variable permanently prevents a party from executing non-unanimous arbitrary call proposals and poses a high security risk.
Audit: 2023-10-party-findings
Severity: HIGH

# Lines of code

https://github.com/PartyDAO/party-protocol/blob/37dae4292dde2547a3b1ced8a041f926e1b37d58/contracts/party/PartyGovernance.sol#L212


# Vulnerability details


### Overview of the `execute()` function in `PartyGovernance`
---
Before diving into the details of the vulnerability, I need to explain how the [`execute()`](https://github.com/PartyDAO/party-protocol/blob/37dae4292dde2547a3b1ced8a041f926e1b37d58/contracts/party/PartyGovernance.sol#L697) function works in the `PartyGovernance.sol` contract.

The [`execute()`](https://github.com/PartyDAO/party-protocol/blob/37dae4292dde2547a3b1ced8a041f926e1b37d58/contracts/party/PartyGovernance.sol#L697) is the function responsible for executing a proposal after it has gotten enough votes to pass plus the execution delay is over. You supply it with the ID of the proposal you want to execute and the `Proposal` object of the proposal you want to execute. Then it compares the hash of the proposal ID you submitted with the hash of the `Proposal` object you submitted. If they match, the function will go on.

Additionally, along with the supplied proposal ID and the `Proposal` object, you also need to supply the correct list of precious NFT tokens which the party was initialized with. You supply the two arrays, `preciousTokens` and `preciousTokenIds`. The `preciousTokens` array contains the addresses of the precious NFT tokens and the `preciousTokensIds` contains the IDs of the precious NFT tokens themselves.

After you have supplied the function with both arrays, it will compare the computed hash of those two arrays with the hash of the two initially-set `preciousTokens` and `preciousTokensIds` arrays during the [initialization of the party](). If they match, then the function will continue.

```solidity
        // Check that the precious list is valid.
        if (!_isPreciousListCorrect(preciousTokens, preciousTokenIds)) {
            revert BadPreciousListError();
        }

```
```solidity
    function _isPreciousListCorrect(
        IERC721[] memory preciousTokens,
        uint256[] memory preciousTokenIds
    ) private view returns (bool) {
        return preciousListHash == _hashPreciousList(preciousTokens, preciousTokenIds);
    }
```

And this is the internal function which calculates the hash of the initially supplied precious token arrays during the intialization of the party. The computed hash is then saved in the state variable `preciousListHash`. [`_setPreciousList()`](https://github.com/PartyDAO/party-protocol/blob/37dae4292dde2547a3b1ced8a041f926e1b37d58/contracts/party/PartyGovernance.sol#L1110C14-L1110C30)
```solidity
    function _isPreciousListCorrect(
        IERC721[] memory preciousTokens,
        uint256[] memory preciousTokenIds
    ) private view returns (bool) {
        return preciousListHash == _hashPreciousList(preciousTokens, preciousTokenIds);
    }
```
```solidity
    ...

    /// @notice The hash of the list of precious NFTs guarded by the party.
    bytes32 pub