# Some arbitrary proposal calls will fail because executeProposal() in ProposalExecutionEngine is not payable

ProposalExecutionEngine.executeProposal() lacks payable, so ArbitraryCallsProposal calls forwarding ETH via msg.value revert, blocking ETH-attached proposals.

- Payout: Contest reward
- Severity: medium
- Program: PartyDAO
- Credited: Arz
- Disclosed: 2024-01-10
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-10-party-findings/issues/475
- Library page: https://bugbountylibrary.com/r/c4%3A2023-10-party%3AM-01
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:business-logic

**Target:** ProposalExecutionEngine.executeProposal / ArbitraryCallsProposal
**Root cause:** executeProposal() is not marked payable, so calls carrying msg.value revert even though delegatecall from payable PartyGovernance.execute() preserves value and _executeArbitraryCalls() relies on msg.value for ethAvailable.
**Steps:**
1. Submit an ArbitraryCallsProposal with allowArbCallsToSpendPartyEth=false and attach ETH (msg.value>0) via PartyGovernance.execute()
2. PartyGovernance.execute() delegatecalls ProposalExecutionEngine.executeProposal()
3. executeProposal() is non-payable, so the call with nonzero value reverts
4. Proposal cannot execute; ETH-attached arbitrary calls fail
**How found:** Code reading of executeProposal() signature vs _executeArbitraryCalls() use of msg.value; noted delegatecall preserves msg.value but callee must still be payable.
**Insight:** When auditing delegatecall-based execution engines, check that the implementation function's mutability (payable) matches the value semantics the caller forwards; delegatecall preserves msg.value but a non-payable callee still reverts on nonzero value.
