# ArbitraryCallsProposal.sol and ListOnOpenseaProposal.sol safeguards can be bypassed by cancelling in-progress proposal allowing the majority to steal NFT

Cancelling a mid-step ListOnOpensea proposal skips cleanup, leaving OpenSea approval intact so majority can relist and buy the party's NFT cheaply.

- Payout: Contest reward
- Severity: high
- Program: PartyDAO
- Credited: 0x52
- Disclosed: 2022-11-17
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-09-party-findings/issues/153
- Library page: https://bugbountylibrary.com/r/c4%3A2022-09-party%3AH-05
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic vuln:governance

**Target:** PartyDAO governance proposal contracts (ArbitraryCallsProposal, ListOnOpenseaProposal, PartyGovernance)
**Root cause:** PartyGovernance.cancel terminates an in-progress proposal without running proposal-specific cleanup, so _cleanUpListing never revokes the OpenSea approval granted in an earlier step.
**Steps:**
1. Create ListOnOpenseaProposal with high sell price and short cancelDelay; pass with majority vote.
2. Execute step 1: list NFT on Zora at high price; wait for auction to end unsold.
3. Execute step 2: list on OpenSea, granting approval to OpenSea contract.
4. Wait cancelDelay, call `PartyGovernance.cancel` — bypasses `_cleanUpListing`, approval persists.
5. Create ArbitraryCallsProposal listing NFT on OpenSea for near-zero; ownership unchanged and no approve selector, so no unanimity needed.
6. Approve and execute, then buy the NFT cheaply.
**How found:** Read the safeguards in ArbitraryCallsProposal (ownership check, approve-selector blacklist) and ListOnOpenseaProposal (_cleanUpListing revokes approval), then noticed cancel terminates mid-step without invoking cleanup, leaving approval dangling.
**Exploitation:** Majority holders pass a listing proposal, advance it to the step that grants OpenSea approval, then cancel after cancelDelay to skip cleanup. The lingering approval lets a follow-up non-unanimous arbitrary-call proposal list the NFT at a trivial price, which the majority then purchases.
**Escalation:** Chains cancel-without-cleanup with the arbitrary-call safeguard gap (only approve selectors blacklisted, ownership check passes) to convert governance majority into NFT theft.
**Insight:** Multi-step proposals that grant temporary approvals rely on a final cleanup step; check whether every exit path (cancel, expire, revert) runs that cleanup, and whether a follow-up proposal can exploit the leftover approval without triggering the ownership/selector guards.
