Failure Modes
failure-modes.md
Boundary
This route preserves legacy markdown access inside the Next.js surface. The raw repository file remains authoritative.
Open raw fileFailure Modes
1. Execute with mismatched treasury
Scenario
An attacker supplies a treasury PDA derived from another DAO while keeping the proposal valid.
Trigger
execute_proposal with a valid-looking but semantically wrong treasury account.
Expected Safe Outcome
The instruction must fail before execution effects occur.
Verified Protection
- 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
Remaining Risk
No direct protocol gap observed in this path.
2. Finalize using wrong dao context
Scenario
A permissionless finalizer submits a correct proposal with an incorrect DAO account.
Trigger
finalize_proposal with mismatched dao / proposal.
Expected Safe Outcome
The instruction fails on seed or has_one validation and proposal fields remain unchanged.
Verified Protection
- proposal PDA is DAO-bound
- failed finalize leaves status and unlock fields unchanged
Reference:
tests/full-flow-test.ts
Remaining Risk
No direct protocol gap observed in this path.
3. Reveal using wrong voter
Scenario
An attacker attempts to reveal another voter’s commit.
Trigger
reveal_vote signed by a different signer than the voter or authorized keeper.
Expected Safe Outcome
The reveal is rejected and tallies remain unchanged.
Verified Protection
revealermust equal voter or keeper- mismatched reveal signer rejected
Reference:
tests/private-dao.ts
Remaining Risk
Metadata timing remains observable even when vote content stays hidden.
4. Commit using stale or cross-proposal delegation
Scenario
A delegatee tries to consume a delegation PDA that belongs to another proposal.
Trigger
commit_delegated_vote with a valid delegation account from the wrong proposal.
Expected Safe Outcome
The instruction fails and the delegation remains unused.
Verified Protection
- delegation PDA is proposal-bound
- failed delegated commit does not set
is_used
Reference:
tests/private-dao.ts
Remaining Risk
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.
5. Replay execution attempt
Scenario
An attacker replays execute after a successful treasury transfer.
Trigger
A second execute_proposal call with the same proposal.
Expected Safe Outcome
The second call is rejected and no second transfer occurs.
Verified Protection
AlreadyExecuted- treasury delta asserted to match only one execution
Reference:
tests/full-flow-test.ts
Remaining Risk
No duplicate execution path is currently observed in tests.
6. Malformed but valid-looking token accounts
Scenario
An attacker supplies initialized token accounts with incorrect mint, owner, or source semantics.
Trigger
SendToken execution with wrong destination owner, wrong mint, duplicate source/destination, or non-treasury source ownership.
Expected Safe Outcome
Execution fails before any token transfer and proposal remains unexecuted.
Verified Protection
- 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
Remaining Risk
No direct protocol gap observed in this path.
7. Partial execution attempt
Scenario
A treasury execute path fails after lifecycle checks but before intended funds transfer.
Trigger
Miswired execute path or invalid treasury account arrangement.
Expected Safe Outcome
No partial treasury movement and no lifecycle advancement.
Verified Protection
- failed execute paths are asserted to preserve
is_executed - balances and status remain stable until a successful execute
Reference:
tests/full-flow-test.ts
Remaining Risk
Relies on Solana transaction atomicity as a trust assumption.
8. Cross-proposal voter-record misuse
Scenario
A voter record from Proposal A is supplied to Proposal B.
Trigger
commit_vote with a PDA derived from another proposal.
Expected Safe Outcome
Seed validation failure before vote state mutates.
Verified Protection
- vote record PDA includes proposal key
Reference:
tests/private-dao.ts
Remaining Risk
No direct protocol gap observed in this path.
9. Authority substitution attempt
Scenario
A non-authority attempts an authority-only action, or a valid signer attempts permissionless action with wrong authority-related context.
Trigger
cancel_proposal, veto_proposal, or confused binding around finalize/execute contexts.
Expected Safe Outcome
Authority-only paths reject the signer; permissionless paths still reject wrong account context.
Verified Protection
has_one = authority- DAO/proposal/treasury binding checks
Reference:
programs/private-dao/src/lib.rstests/full-flow-test.ts
Remaining Risk
Authority-only paths are logic-protected, but explicit authority misuse tests are thinner than execute/finalize path tests.
10. Invalid PDA substitution
Scenario
An attacker uses valid initialized accounts that are not the exact PDAs expected by the protocol.
Trigger
Substitution against proposal, voter record, delegation, or treasury.
Expected Safe Outcome
Seed or relationship constraints fail before any state mutation.
Verified Protection
- PDA seeds tie accounts to DAO/proposal/voter/delegator relationships
Reference:
tests/private-dao.tstests/full-flow-test.ts
Remaining Risk
No direct protocol gap observed in tested substitution paths.