Skip to content

Feature/vesting vaults - #99

Merged
bakarezainab merged 4 commits into
LatterFixxx:mainfrom
Mainnet-ops:feature/vesting-vaults
Aug 21, 2026
Merged

Feature/vesting vaults#99
bakarezainab merged 4 commits into
LatterFixxx:mainfrom
Mainnet-ops:feature/vesting-vaults

Conversation

@Mainnet-ops

@Mainnet-ops Mainnet-ops commented Aug 20, 2026

Copy link
Copy Markdown

Summary

Closes #88

Implement time-locked vesting vaults for approved milestone payouts. When a milestone is approved, funds can now be held in a vesting state for a configurable safety window (1 hour to 30 days) during which admins or task creators can open disputes. If no dispute is raised within the window, the beneficiary can claim the full payout.

Changes

New Module: src/vesting_vault.rs

  • VestingVault struct with status tracking (Active → Disputed → Released/Refunded)
  • Storage keys for vault-by-ID, task vaults, beneficiary vaults, and milestone vaults
  • Core functions:
    • create_vesting_vault — locks escrowed funds for a safety window
    • dispute_vesting_vault — allows admin/creator to open disputes during vesting
    • release_vesting_vault — releases funds after vesting period ends
    • refund_vesting_vault — refunds disputed vaults to task creator
  • View functions: get_vault, get_task_vaults, get_beneficiary_vaults
  • Time tracking: is_vesting_complete, get_remaining_vesting_time

Contract Integration: src/lib.rs

  • create_vesting_vault — create time-locked vault for milestone payout
  • approve_milestone_with_vesting — approve milestone and create vault in one step
  • dispute_vesting_vault — open dispute during vesting period
  • release_vesting_vault — release funds after vesting ends
  • refund_vesting_vault — refund disputed vault to creator
  • View methods for vault details and time tracking

Events: src/events.rs

  • emit_vesting_vault_created — emitted when a new vault is created
  • emit_vesting_vault_disputed — emitted when a vault is disputed
  • emit_vesting_vault_released — emitted when funds are released
  • emit_vesting_vault_refunded — emitted when disputed funds are refunded

Tests: src/vesting_vault_test.rs

  • 12 comprehensive unit tests covering all vault lifecycle paths

Testing

Test command: cargo test --lib vesting_vault_test

Results: 12/12 tests passing

Test Description
test_create_vesting_vault Verify vault creation and fund locking
test_cannot_release_before_vesting_ends Enforce time lock before vesting period
test_release_after_vesting_ends Verify successful release after vesting
test_dispute_during_vesting_period Verify dispute mechanism works
test_cannot_release_disputed_vault Block release when vault is disputed
test_refund_disputed_vault Verify refund flow to task creator
test_cannot_dispute_after_vesting_ends Enforce dispute window deadline
test_vesting_time_tracking Verify time tracking functions
test_admin_can_release_vault Admin can release on behalf of beneficiary
test_cannot_create_vault_for_non_approved_milestone Reject non-approved milestones
test_cannot_create_duplicate_vault Prevent duplicate vaults per milestone
test_multiple_vaults_different_milestones Support multiple vaults per task

Full suite: cargo test --lib → 113 tests passing (12 new + 101 existing)

Tradeoffs

  • Vesting period bounds: Set minimum 1 hour and maximum 30 days. Shorter periods reduce dispute window effectiveness; longer periods lock funds unnecessarily.
  • Dispute authority: Only admin or task creator can dispute. Assignee cannot self-dispute to prevent abuse.
  • Release authority: Both beneficiary and admin can release after vesting ends. This allows admin to release if beneficiary is unresponsive.
  • No partial release: Vault releases full amount only. Partial claims would add complexity without clear benefit for milestone payouts.

Architecture

The vesting vault operates on escrowed funds already held by the contract from task creation. The approve_milestone_with_vesting method creates a vault instead of transferring tokens immediately, keeping funds locked until the vesting period expires or a dispute is resolved.

Task Created → Milestone Submitted → Milestone Approved
                                          ↓
                              Vesting Vault Created
                                          ↓
                              ┌───────────┴───────────┐
                              ↓                       ↓
                        No Dispute              Dispute Opened
                              ↓                       ↓
                        Release to              Refund to
                        Beneficiary             Task Creator



## Out of Scope

- Partial vesting releases (only full amount release supported)
- Assignee-initiated disputes (only admin/creator can dispute)
- Configurable dispute resolution (uses existing dispute resolution flow)
- Vesting vault integration with Merkle payroll (separate feature)

“Mainnet-ops” added 4 commits January 15, 2025 08:00
Implement core vesting vault functionality:
- VestingVault struct with status tracking (Active, Disputed, Released, Refunded)
- Storage keys for vault mappings and indexing
- create_vesting_vault: locks escrowed funds for a safety window
- dispute_vesting_vault: allows admin/creator to open disputes during vesting
- release_vesting_vault: releases funds after vesting period ends
- refund_vesting_vault: refunds disputed vaults to task creator
- View functions for vault details, task vaults, and beneficiary vaults
- Time tracking functions (is_vesting_complete, get_remaining_vesting_time)
Add structured events for vesting vault operations:
- emit_vesting_vault_created: emitted when a new vault is created
- emit_vesting_vault_disputed: emitted when a vault is disputed
- emit_vesting_vault_released: emitted when funds are released
- emit_vesting_vault_refunded: emitted when disputed funds are refunded

Events follow existing contract patterns with symbol_short topics and
timestamp data for off-chain indexing.
Add contract-level methods for vesting vault operations:
- create_vesting_vault: create time-locked vault for milestone payout
- approve_milestone_with_vesting: approve milestone and create vault in one step
- dispute_vesting_vault: open dispute during vesting period
- release_vesting_vault: release funds after vesting ends
- refund_vesting_vault: refund disputed vault to creator
- View methods for vault details and time tracking

The approve_milestone_with_vesting method allows creators to approve
milestones while keeping funds locked for a safety window, enabling
disputes before final payout.
Add 12 unit tests validating vesting vault functionality:
- test_create_vesting_vault: verify vault creation and fund locking
- test_cannot_release_before_vesting_ends: enforce time lock
- test_release_after_vesting_ends: verify successful release
- test_dispute_during_vesting_period: verify dispute mechanism
- test_cannot_release_disputed_vault: block release on dispute
- test_refund_disputed_vault: verify refund to creator
- test_cannot_dispute_after_vesting_ends: enforce dispute window
- test_vesting_time_tracking: verify time tracking functions
- test_admin_can_release_vault: admin release capability
- test_cannot_create_vault_for_non_approved_milestone: validation
- test_cannot_create_duplicate_vault: prevent duplicates
- test_multiple_vaults_different_milestones: multiple vaults

All 113 tests passing (12 new + 101 existing).
@bakarezainab
bakarezainab merged commit a546ebd into LatterFixxx:main Aug 21, 2026
1 check passed
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.

#079: Time-Locked Milestone Vesting Vaults

2 participants