This document describes the implementation of Draft state support for both Bounty Escrow and Program Escrow contracts in Grainlify.
-
Added
Draftstatus toEscrowStatusenum (lib.rs:650)pub enum EscrowStatus { Draft, // ← NEW Locked, Released, Refunded, PartiallyRefunded, }
-
Updated escrow creation to start in Draft status
lock_funds()- Line 2656lock_funds_anonymous()- Line 2984batch_lock_funds()- Line 4511
All now create escrows with
status: EscrowStatus::Draft -
Added
publish()function (Lines 3036-3094)- Admin-only function to transition escrow from Draft → Locked
- Emits
EscrowPublishedevent - Validates escrow exists and is in Draft status
-
Updated
release_funds()to block Draft status (Lines 3143-3151)- Explicit check for Draft status before allowing release
- Returns
Error::InvalidStateif Draft
-
Updated
refund()to block Draft status (Lines 3880-3892)- Explicit check for Draft status before allowing refund
- Returns
Error::InvalidStateif Draft
-
Updated capability token checks (Lines 2005-2010, 2026-2034, 2091-2096, 2113-2117)
- Both Release and Refund capability actions now block Draft status
-
Added
EscrowPublishedevent (events.rs:169-207)- Event structure and emitter function
- Emitted when escrow transitions Draft → Locked
[New] ──lock_funds()──► Draft ──publish()──► Locked ──release/refund──► Terminal States
-
Added
ProgramStatusenum (lib.rs:427-444)pub enum ProgramStatus { Draft, // Initial state Active, // Published state }
-
Updated
ProgramDatastruct (Line 459)- Added
status: ProgramStatusfield
- Added
-
Updated
init_program()to create in Draft status (Line 1053)- Programs now start with
status: ProgramStatus::Draft
- Programs now start with
-
Updated
lock_program_funds()to block Draft (Lines 1428-1441)- Checks program status before allowing fund locks
- Panics with "Program is in Draft status" if not published
-
Add
publish_program()function- Should transition program from Draft → Active
- Admin/creator only
- Emit
ProgramPublishedevent
-
Update payout functions to block Draft
single_payout()batch_payout()- Check program status before allowing payouts
-
Update refund functions to block Draft
- Any program refund functions
- Check program status
-
Add
ProgramPublishedevent- Similar to
EscrowPublishedevent - Track Draft → Active transitions
- Similar to
-
Test Draft → Locked transition
#[test] fn test_escrow_starts_in_draft_status() fn test_publish_transitions_to_locked() fn test_publish_fails_if_not_draft()
-
Test operations blocked in Draft
#[test] #[should_panic(expected = "InvalidState")] fn test_release_fails_in_draft_status() #[test] #[should_panic(expected = "InvalidState")] fn test_refund_fails_in_draft_status()
-
Test capability tokens blocked in Draft
#[test] fn test_capability_release_blocked_in_draft() fn test_capability_refund_blocked_in_draft()
-
Test program starts in Draft
#[test] fn test_program_starts_in_draft_status() fn test_publish_program_transitions_to_active()
-
Test lock_program_funds blocked in Draft
#[test] #[should_panic(expected = "Draft status")] fn test_lock_funds_fails_in_draft_status()
-
Test payouts blocked in Draft (after publish_program added)
#[test] fn test_payout_fails_in_draft_status()
- Bounty Escrow: Existing escrows were created with
Lockedstatus, so they are unaffected - Program Escrow: Existing programs need migration to add the
statusfield- Default existing programs to
ProgramStatus::Activeto maintain current behavior - OR run a migration script to set status based on whether funds are locked
- Default existing programs to
- The
Draftenum variant is additive, so it won't break existing queries filtering by other statuses - New validation checks may break existing integrations that expect immediate lock/release
-
Access Control:
publish()is admin-only (bounty escrow)publish_program()should also be admin/creator-only
-
State Validation:
- All state-changing operations must check for Draft status
- Audit all functions that interact with escrow/program state
-
Event Emission:
- Publish events are critical for off-chain tracking
- Indexers need to handle Draft status properly
- ✅ Complete bounty escrow tests
⚠️ Addpublish_program()function⚠️ Update program payout functions to block Draft⚠️ Add program escrow tests
- Add query functions to filter by Draft status
- Add metadata update capability in Draft state
- Consider allowing draft editing before publish
- Add deadline handling for unpublished drafts
-
contracts/bounty_escrow/contracts/escrow/src/lib.rs- Lines 650-655: Added Draft to EscrowStatus
- Lines 2656, 2984, 4511: Updated to create Draft escrows
- Lines 3036-3094: Added publish() function
- Lines 3143-3151: Updated release_funds check
- Lines 3880-3892: Updated refund check
- Lines 2005-2010, 2026-2034, 2091-2096, 2113-2117: Capability checks
-
contracts/bounty_escrow/contracts/escrow/src/events.rs- Lines 169-207: Added EscrowPublished event
contracts/program-escrow/src/lib.rs- Lines 427-444: Added ProgramStatus enum
- Line 459: Added status field to ProgramData
- Line 1053: Set initial status to Draft
- Lines 1428-1441: Updated lock_program_funds check
BountyEscrowContract::publish(bounty_id: u64)- Transition escrow Draft → LockedProgramEscrowContract::publish_program(program_id: String)- TODO
lock_funds()- Now creates Draft escrows (not immediately Locked)lock_program_funds()- Now blocked until program is publishedrelease_funds()- Now blocked for Draft escrowsrefund()- Now blocked for Draft escrows
EscrowPublished- Emitted when bounty escrow is publishedProgramPublished- TODO
- Update ARCHITECTURE.md with new state machine diagrams
- Add Draft state explanation to README files
- Update API documentation
- Create migration guide for existing deployments
- Add developer guide for using Draft state
The Draft state implementation is complete for Bounty Escrow and partially complete for Program Escrow. The feature enables safer contract interactions by requiring an explicit publish step before funds can be moved, preventing accidental operations during setup.
Estimated completion time for remaining work: 2-4 hours Risk level: Low - changes are additive and don't affect existing deployed contracts Testing priority: High - state machine changes require thorough testing