Skip to content

feat(contract): add on-chain proposal voting system#59

Merged
codebestia merged 2 commits into
codebestia:mainfrom
Depo-dev:feat/proposal-voting-39
May 31, 2026
Merged

feat(contract): add on-chain proposal voting system#59
codebestia merged 2 commits into
codebestia:mainfrom
Depo-dev:feat/proposal-voting-39

Conversation

@Depo-dev

Copy link
Copy Markdown
Contributor

Summary

  • Implements on-chain proposal voting and execution in a new proposals Soroban contract
  • Also adds the group_treasury contract whose withdraw entry-point the proposals contract calls on execution
  • 13 proposals tests + 7 treasury tests; all pass with cargo test

Voting architecture

cast_vote(voter, proposal_id, approve):

  • Requires voter authorization
  • Panics "voting period has ended" if ledger.timestamp >= proposal.end_time
  • Panics "already voted" if the voter has previously cast a vote on this proposal
  • Increments yes_votes or no_votes and persists the voter record

execute_proposal(proposal_id):

  • Panics "voting period not yet ended" if the period is still open
  • Panics "proposal already executed" on re-execution attempts
  • Marks proposal executed, then calls treasury.withdraw(recipient, amount) only when yes_votes > no_votes

Storage strategy

  • Proposal structs stored in persistent storage keyed by DataKey::Proposal(u32)
  • Voter records stored as DataKey::Voted(proposal_id, voter_address) -> bool
  • Contract config (admin, treasury, next ID) in instance storage

Double-vote prevention

Each (proposal_id, voter_address) pair has a dedicated persistent storage entry. Attempting a second vote panics immediately.

Expiry logic

end_time is set at proposal creation as ledger.timestamp + duration_secs. Votes are rejected when timestamp >= end_time; execution requires timestamp >= end_time.

Treasury execution flow

TreasuryClient (defined via contractclient trait interface) is called with (recipient, amount). The treasury contract gates withdraw behind proposals_contract.require_auth(), automatically satisfied by the cross-contract call.

Tests added

  • proposals: 13 passed
  • group_treasury: 7 passed
  • token_transfer: 5 passed (existing, unaffected)

Fixes #39

Adds proposals Soroban contract with cast_vote/execute_proposal:
double-vote prevention, expiry enforcement, yes>no pass threshold,
and cross-contract treasury withdraw on passed proposals. Also adds
group_treasury contract gating withdraw behind the proposals contract.
20 tests cover all acceptance criteria.

Fixes codebestia#39
@drips-wave

drips-wave Bot commented May 29, 2026

Copy link
Copy Markdown

@Depo-dev Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@codebestia codebestia left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
Thanks

@codebestia

Copy link
Copy Markdown
Owner

Please resolve the conflicts.

Adopt upstream/main's refined contract designs:
- GroupTreasury: admin-only withdraw, no ProposalsContract coupling
- Proposals: finalize_proposal + execute separation, ProposalStatus enum

@codebestia codebestia left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!
Thanks

@codebestia codebestia merged commit d832bfb into codebestia:main May 31, 2026
0 of 2 checks passed
codebestia added a commit that referenced this pull request Jun 26, 2026
feat(contract): add on-chain proposal voting system
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CONTRACT] Implement on-chain voting for proposals

2 participants