An attacker supplies a treasury PDA derived from another DAO while keeping the proposal valid.
execute_proposal with a valid-looking but semantically wrong treasury account.
The instruction must fail before execution effects occur.
- treasury account is seed-bound to the supplied DAO
- proposal is
has_one = dao - failed path leaves
is_executed = false
Reference:
tests/full-flow-test.ts
No direct protocol gap observed in this path.
A permissionless finalizer submits a correct proposal with an incorrect DAO account.
finalize_proposal with mismatched dao / proposal.
The instruction fails on seed or has_one validation and proposal fields remain unchanged.
- proposal PDA is DAO-bound
- failed finalize leaves status and unlock fields unchanged
Reference:
tests/full-flow-test.ts
No direct protocol gap observed in this path.
An attacker attempts to reveal another voter’s commit.
reveal_vote signed by a different signer than the voter or authorized keeper.
The reveal is rejected and tallies remain unchanged.
revealermust equal voter or keeper- mismatched reveal signer rejected
Reference:
tests/private-dao.ts
Metadata timing remains observable even when vote content stays hidden.
A delegatee tries to consume a delegation PDA that belongs to another proposal.
commit_delegated_vote with a valid delegation account from the wrong proposal.
The instruction fails and the delegation remains unused.
- delegation PDA is proposal-bound
- failed delegated commit does not set
is_used
Reference:
tests/private-dao.ts
Direct/delegated overlap is now rejected on-chain through proposal-bound vote and delegation marker accounts. Product surfaces still mirror that same check for clearer operator feedback.
An attacker replays execute after a successful treasury transfer.
A second execute_proposal call with the same proposal.
The second call is rejected and no second transfer occurs.
AlreadyExecuted- treasury delta asserted to match only one execution
Reference:
tests/full-flow-test.ts
No duplicate execution path is currently observed in tests.
An attacker supplies initialized token accounts with incorrect mint, owner, or source semantics.
SendToken execution with wrong destination owner, wrong mint, duplicate source/destination, or non-treasury source ownership.
Execution fails before any token transfer and proposal remains unexecuted.
- recipient owner match
- mint match on source and destination
- treasury ownership match
- source/destination non-duplication
is_executedremains false on failed paths
Reference:
tests/full-flow-test.ts
No direct protocol gap observed in this path.
A treasury execute path fails after lifecycle checks but before intended funds transfer.
Miswired execute path or invalid treasury account arrangement.
No partial treasury movement and no lifecycle advancement.
- failed execute paths are asserted to preserve
is_executed - balances and status remain stable until a successful execute
Reference:
tests/full-flow-test.ts
Relies on Solana transaction atomicity as a trust assumption.
A voter record from Proposal A is supplied to Proposal B.
commit_vote with a PDA derived from another proposal.
Seed validation failure before vote state mutates.
- vote record PDA includes proposal key
Reference:
tests/private-dao.ts
No direct protocol gap observed in this path.
A non-authority attempts an authority-only action, or a valid signer attempts permissionless action with wrong authority-related context.
cancel_proposal, veto_proposal, or confused binding around finalize/execute contexts.
Authority-only paths reject the signer; permissionless paths still reject wrong account context.
has_one = authority- DAO/proposal/treasury binding checks
Reference:
programs/private-dao/src/lib.rstests/full-flow-test.ts
Authority-only paths are logic-protected, but explicit authority misuse tests are thinner than execute/finalize path tests.
An attacker uses valid initialized accounts that are not the exact PDAs expected by the protocol.
Substitution against proposal, voter record, delegation, or treasury.
Seed or relationship constraints fail before any state mutation.
- PDA seeds tie accounts to DAO/proposal/voter/delegator relationships
Reference:
tests/private-dao.tstests/full-flow-test.ts
No direct protocol gap observed in tested substitution paths.