Prohibit Vote Account Self-Withdrawals
- Idea
- Draft
- Review
- Accept
- Implement
- Active
Decision brief
Why this proposal matters
Reject a Vote Program Withdraw instruction when the vote account and recipient resolve to the same address. After activation, every authorized self-withdrawal returns InvalidArgument. Other withdrawals are unchanged.
Proposal at a glance
What changes
- Validate the vote account and authorized withdrawer using the existing rules.
- Compare the addresses of the vote account and recipient.
- If the addresses match, return InvalidArgument.
Stakeholder map
Who is affected
Builders & client teams Medium impact
Because the Vote Program is a native builtin, validator clients must implement the same feature-gated behavior before activation.
Action may be requiredValidators & operators Medium impact
After activation, vote account self-withdrawals fail with InvalidArgument. Non-self withdrawals, instruction encoding, and account lists are unchanged.
Action requirement unknownUsers & stakers Impact unknown
No proposal-specific evidence was found for this group.
Action requirement unknownGovernance & ecosystem Impact unknown
No proposal-specific evidence was found for this group.
Action requirement unknownExact source revision
Full proposal document
6cc17538e266Summary
Reject a Vote Program Withdraw instruction when the vote account and recipient
resolve to the same address. After activation, every authorized self-withdrawal
returns InvalidArgument. Other withdrawals are unchanged.
Motivation
Currently, a Vote Program Withdraw instruction may use the same account as the
vote account and recipient. A partial self-withdrawal that passes existing checks
subtracts and then restores the requested lamports, making it a no-op.
A full self-withdrawal behaves differently. It deinitializes the vote account, subtracts its full balance, and restores the lamports to the same account. This leaves a funded, Vote Program owned, uninitialized account. Anyone else can then initialize that account with their own validator identity and authorities, taking control of the retained balance. Initiating the self-withdrawal requires the existing authorized withdrawer, making the behavior an operator footgun.
Self-withdrawals have no known use case. Rejecting them removes this risk. The
Stake Program already rejects self-withdrawals with InvalidArgument.
New Terminology
N/A
Detailed Design
Vote Program Withdraw processes an instruction in this order:
- Validate the vote account and authorized withdrawer using the existing rules.
- Compare the addresses of the vote account and recipient.
- If the addresses match, return
InvalidArgument. - If the addresses differ, continue existing withdrawal processing.
The new comparison precedes withdrawal amount and account closure checks. It therefore applies to zero, partial, full-balance, and over-balance withdrawals.
The instruction data and account interface do not change.
Alternatives Considered
- Reject only full self-withdrawals. This prevents vote account deinitialization but preserves partial and zero-lamport no-op transactions without a known use.
- Skip deinitialization for full self-withdrawals. This makes them no-ops and leaves a special case that future changes must continue to handle safely.
- Reject self-withdrawals only in the SDK and CLI. Custom transaction builders can bypass client-side checks, so this does not enforce the invariant.
- Keep the existing behavior. This preserves the footgun.
Impact
After activation, vote account self-withdrawals fail with InvalidArgument.
Non-self withdrawals, instruction encoding, and account lists are unchanged.
Because the Vote Program is a native builtin, validator clients must implement the same feature-gated behavior before activation.
Security Considerations
N/A
Evidence graph
Related proposals and rollout
One or more sources are unavailable.
Upstream review record
Upstream discussion & review
One or more sources are unavailable.
Provenance
Evidence & technical details
Rollout or chain data, source revisions, freshness and integrity. 3
Provenance
Evidence & technical details
Rollout or chain data, source revisions, freshness and integrity.SIMD
Deployment Status
Feature Gate not yet created
Exact source revision
Sources & integrity
- Proposal document pinned_commit_blob
6cc17538e26601e65beca89bbfa761e755720956 - simd-document document · stale · Oct 29, 2026
6cc17538e26601e65beca89bbfa761e755720956
One or more sources are unavailable.
One or more sources are unavailable.
simd.watch community discussion · SIMD-0609
Powered by Giscus · Sign in with GitHub to comment
Community comments load when this section approaches the viewport.