This document tracks all smart contract development tasks for the OrbitPay protocol. Each issue is self-contained and can be picked up independently.
When you complete an issue:
- Mark the checkbox
[x] - Append your GitHub username and the Date/Time.
- Example:
- [x] Define Error enum (@yourname - 2026-02-18 15:00 UTC)
Priority: Critical
Labels: smart-contract, good-first-issue, treasury
Description: Review and extend the error constants defined in contracts/treasury/src/errors.rs.
- Tasks:
- Add
InsufficientBalanceerror variant (u12). - Add
ProposalExpirederror variant (u13). - Add helper function
require_initialized(env) -> Result<()>to reduce boilerplate. - Write doc comments for each error explaining when it's triggered.
- Add
Priority: High
Labels: smart-contract, storage, treasury
Description: Add TTL (Time-to-Live) management for persistent storage entries.
- Tasks:
- Implement
extend_instance_ttl(env)with appropriate ledger bump. - Implement
extend_withdrawal_ttl(env, id)for persistent withdrawal records. - Call TTL extension in
initialize()andcreate_withdrawal().
- Implement
Priority: Medium
Labels: smart-contract, query, treasury
Description: Implement a get_config() function that returns a TreasuryConfig snapshot.
- Tasks:
- Implement
get_config(env) -> TreasuryConfigusing the struct intypes.rs. - Return admin, signers, threshold, and proposal_count in one call.
- Add unit test for
get_config.
- Implement
Priority: Critical
Labels: smart-contract, integration, treasury
Description: Complete the deposit() function by integrating the Soroban token client.
- Tasks:
- Import
soroban_sdk::tokenmodule. - Create
token::Clientand invoke.transfer()from depositor to contract. - Add a
get_balance(env, token)query that reads the contract's token balance. - Add unit test: deposit and verify balance changes.
- Import
Priority: Critical
Labels: smart-contract, integration, treasury
Description: Complete the execute_withdrawal() function with actual token transfers.
- Tasks:
- Use
token::Clientto transfer from contract torequest.recipient. - Verify contract has sufficient balance before transfer.
- Emit
WithdrawalExecutedevent with amount and recipient. - Add unit test: full flow from deposit β create β approve β execute β verify balances.
- Use
Priority: Medium
Labels: smart-contract, logic, treasury
Description: Implement a cancel_withdrawal() function.
- Tasks:
- Only the original proposer or admin can cancel.
- Can only cancel
Pendingproposals. - Set status to
Cancelled. - Emit
WithdrawalCancelledevent. - Add unit test for cancellation.
Priority: Medium
Labels: smart-contract, events, treasury
Description: Standardize all treasury events for off-chain indexing.
- Tasks:
- Define consistent event topic naming:
TreasuryDeposit,WithdrawalCreated, etc. - Include structured data in events (amount, token, addresses).
- Create a reference document in
docs/listing all event schemas.
- Define consistent event topic naming:
Priority: High
Labels: testing, rust, treasury
Description: Expand the treasury test suite with edge cases.
- Tasks:
- Test unauthorized withdrawal attempt (non-signer).
- Test threshold update with boundary values.
- Test removing signer when at threshold minimum.
- Test double-approval by same signer rejected.
- Test execute before approval threshold met.
- Test invalid threshold (0 or > signers) rejected at init.
Priority: High
Labels: smart-contract, logic, payroll
Description: Implement pause and resume functionality for active streams.
- Tasks:
- Add
pause_stream(env, sender, stream_id)function. - Add
resume_stream(env, sender, stream_id)function. - Only the sender (org) can pause/resume.
- Update
calculate_claimableto account for paused periods. - Add
paused_at: Option<u64>field to PayrollStream struct. - Add
total_paused_duration: u64field.
- Add
Priority: Critical
Labels: smart-contract, integration, payroll
Description: Wire up actual token transfers in create_stream and claim.
- Tasks:
- In
create_stream: transfertotal_amountfrom sender to contract. - In
claim: transfer claimable tokens from contract to recipient. - In
cancel_stream: transfer remaining to sender, owed to recipient. - Handle edge case: stream with zero claimable on cancel.
- In
Priority: Medium
Labels: smart-contract, feature, payroll
Description: Add a create_batch_streams() function for bulk payroll setup.
- Tasks:
- Accept a
Vecof stream parameters. - Create multiple streams in a single contract call.
- Emit a single batch event with all stream IDs.
- Add unit test for batch creation.
- Accept a
Priority: High
Labels: smart-contract, logic, payroll
Description: Implement proper refund splitting on stream cancellation.
- Tasks:
- Calculate exact pro-rata split at cancellation time.
- Transfer owed amount to recipient.
- Transfer remaining (unstreamed) to sender.
- Handle edge case: cancellation before stream starts.
- Handle edge case: cancellation after stream ends.
Priority: Medium
Labels: smart-contract, events, payroll
Description: Define comprehensive events for stream lifecycle.
- Tasks:
-
StreamCreated(sender, recipient, amount, start, end) -
StreamClaimed(recipient, stream_id, amount_claimed) -
StreamCancelled(sender, stream_id, refund_amount) -
StreamPaused(sender, stream_id, paused_at) -
StreamResumed(sender, stream_id, resumed_at)
-
Priority: High
Labels: testing, rust, payroll
Description: Full test coverage for the payroll stream contract.
- Tasks:
- Test claim at various time points (25%, 50%, 75%, 100%).
- Test claim after stream fully completes.
- Test cancel with partial claims already made.
- Test unauthorized cancel by non-sender.
- Test creating stream with invalid amounts/durations.
- Test multiple streams from same sender to different recipients.
Priority: High
Labels: smart-contract, logic, vesting
Description: Add explicit cliff unlock amount that vests instantly at cliff.
- Tasks:
- Add
cliff_amount: i128field toVestingScheduleβ the amount that unlocks at cliff. - Update
calculate_vested()to unlockcliff_amountat cliff time. - Remaining
total_amount - cliff_amountvests linearly after cliff. - Update
create_schedule()to acceptcliff_amountparameter. - Add guard:
cliff_amount <= total_amount.
- Add
Priority: Critical
Labels: smart-contract, integration, vesting
Description: Wire up token transfers in vesting functions.
- Tasks:
- In
create_schedule: transfertotal_amountfrom grantor to contract. - In
claim: transfer claimable amount from contract to beneficiary. - In
revoke: transfer unvested remainder back to grantor. - Add balance verification before transfers.
- In
Priority: Medium
Labels: smart-contract, feature, vesting
Description: Track claim history for each vesting schedule.
- Tasks:
- Define
ClaimRecordstruct:{ amount, timestamp }. - Store claim records in persistent storage keyed by schedule ID.
- Add
get_claim_history(env, schedule_id) -> Vec<ClaimRecord>query. - Update
claim()to append to history.
- Define
Priority: High
Labels: smart-contract, logic, vesting
Description: Complete the revocation logic with token refunds.
- Tasks:
- Transfer unvested tokens back to grantor on revoke.
- Ensure already-claimed + vested-but-unclaimed tokens stay with beneficiary.
- Prevent revocation of non-revocable schedules.
- Add
revoked_at: Option<u64>timestamp to schedule. - Emit
VestingRevoked(grantor, schedule_id, unvested_returned)event.
Priority: Medium
Labels: smart-contract, events, vesting
Description: Define comprehensive events for vesting lifecycle.
- Tasks:
-
VestingCreated(grantor, beneficiary, total_amount, cliff, duration) -
VestingClaimed(beneficiary, schedule_id, amount_claimed) -
VestingRevoked(grantor, schedule_id, unvested_returned) -
VestingFullyClaimed(schedule_id)when all tokens claimed.
-
Priority: High
Labels: testing, rust, vesting
Description: Full test coverage for vesting contract.
- Tasks:
- Test nothing vests before cliff.
- Test exact cliff amount vests at cliff time.
- Test linear vesting at 25%, 50%, 75%.
- Test full vesting after total duration.
- Test claim, then claim again later for remaining.
- Test non-revocable schedule cannot be revoked.
- Test unauthorized revoke by non-grantor.
- Test multiple schedules for same beneficiary.
Priority: Medium
Labels: smart-contract, logic, governance
Description: Allow proposers to cancel their own active proposals.
- Tasks:
- Add
cancel_proposal(env, proposer, proposal_id)function. - Only the original proposer can cancel.
- Can only cancel
Activeproposals. - Set status to
Cancelled. - Emit
ProposalCancelledevent.
- Add
Priority: Medium
Labels: smart-contract, feature, governance
Description: Auto-expire proposals that aren't finalized within a grace period.
- Tasks:
- Add
grace_period: u64to governance config. - In
finalize(), check ifnow > end_time + grace_period. - If expired beyond grace period, auto-reject.
- Add
get_proposal_status(env, proposal_id)that computes live status.
- Add
Priority: Low
Labels: smart-contract, feature, governance
Description: Implement optional weighted voting for governance.
- Tasks:
- Add
voting_weight: Map<Address, u32>to governance config. - Modify
vote()to use voter's weight instead of flat 1. - Add
set_voting_weight(env, admin, member, weight)admin function. - Default weight = 1 for members without explicit weight.
- Update quorum calculation to use total weight, not member count.
- Add
Priority: High
Labels: smart-contract, integration, governance
Description: Connect governance to the treasury for fund disbursement.
- Tasks:
- In
execute(), invoke treasury contract's withdrawal function. - Store treasury contract address in governance config.
- Add
set_treasury(env, admin, treasury_address)admin function. - Verify cross-contract invocation works in tests.
- In
Priority: High
Labels: testing, rust, governance
Description: Full test coverage for governance contract.
- Tasks:
- Test duplicate vote rejected.
- Test vote after voting period expires rejected.
- Test proposal execution flow.
- Test non-member cannot vote.
- Test non-member cannot create proposal.
- Test quorum calculation with different member counts.
- Test add and remove members.
- Test proposal cancellation.
(Move completed items here)