A price feed role owner can remove previously set proposed USD prices at will by constantly setting new proposals and deleting the old one, possibly never allowing a proposal to actually ever go through
Audit: 2024-05-munchables-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-05-munchables/blob/57dff486c3cd905f21b330c2157fe23da2a4807d/src/managers/LockManager.sol#L161
https://github.com/code-423n4/2024-05-munchables/blob/57dff486c3cd905f21b330c2157fe23da2a4807d/src/managers/LockManager.sol#L30


# Vulnerability details

## Impact
A price feed role owner can decide to completely delete a proposal in progress if the approvals/disapprovals don't go in their favor.

## Proof of Concept
The `proposeUSDPrice()` function allows 5 different price feed role owners to make proposals. These proposed prices will either be approved or disapproved depending on if they meet the `APPROVE_THRESHOLD` or `DISAPPROVE_THRESHOLD` values after the other roles make their votes. 

The problem here is that, if a different price feed role owner casted a disapprove on the proposal, but sees that that other roles are approving it and may lead to an actual approval, that owner can deny the approval before it goes through by essentially deleting it by calling `proposeUSDPrice()` and setting a new proposal.

The line of code below is what deletes the struct and resets its values when we call `proposeUSDPrice()`:

```solidity
    delete usdUpdateProposal;
```

The reason this line of code deletes the entire current proposal data is because there is no mapping to each unique proposal struct and causes it to be deleted every single time a proposal is made, effectively erasing the approvals/disapprovals made. If there was a unique id attached to the struct via a mapping, then we can save previously made proposals even if a new one is created. 

In fact, the protocol had this thought in mind already but did not execute it properly. We can see that there is indeed a unique ID for the proposals made so that we can save previously set USD proposals, but it wasn't implemented correctly:

```solidity
// Approvals will use this because when the struct is deleted the approvals remain
++_usdProposalId;
```

## Tools Used
Manual review

## Recommended Mitigation Steps
There are a couple things we need to do. First, it would be best to create a mapping to the struct so that we can have multiple proposals made without having to  delete previous proposals:

```diff
-    USDUpdateProposal usdUpdateProposal;
+    mapping(uint32 => USDUpdateProposal) public proposalIdToStruct;
```  

Now that we have an id attached to each unique proposal, we can change the `proposeUSDPrice()` function to implement this correctly and not have a malicious price feed role owner delete previous proposals:

```diff
function proposeUSDPrice(
        uint256 _price,
        address[] calldata _contracts
    )
        external
        onlyOneOfRoles(
            [
                Role.PriceFeed_1,
                Role.PriceFeed_2,
                Role.PriceFeed_3,
                Role.PriceFeed_4,
                Role.PriceFeed_5
            ]
        )
    {
        if (usdUpdateProposal.proposer != address(0))
            revert ProposalIn