Skip to content

feat(contracts): implement Soroban milestone escrow state machine (#189) - #211

Open
CodeNinjaStephen wants to merge 2 commits into
Lumina-eX:mainfrom
CodeNinjaStephen:feature/soroban-milestone-escrow-state-machine
Open

feat(contracts): implement Soroban milestone escrow state machine (#189)#211
CodeNinjaStephen wants to merge 2 commits into
Lumina-eX:mainfrom
CodeNinjaStephen:feature/soroban-milestone-escrow-state-machine

Conversation

@CodeNinjaStephen

Copy link
Copy Markdown

feat(contracts): Soroban Milestone Escrow State Machine (#189)

Summary

Implements a formal state machine inside the Soroban escrow contract to manage milestone-based
workflows, enforcing predictable transitions, role-based authorization, and secure fund
handling.

Changes

New state: InProgress

Added InProgress between Funded and Submitted, making the full happy path:
Pending → Funded → InProgress → Submitted → Approved → Released

New function: start_milestone(milestone_id)

Client-only call that transitions a milestone from Funded to InProgress, signalling that work
may begin. This prevents freelancers from submitting deliverables before the client has
formally started the milestone.

Updated refund()

Both the client and the freelancer can now initiate a refund (previously freelancer-only).
Valid from Funded or InProgress states only.

Updated dispute()

Disputes can now be raised from InProgress, Submitted, or Approved states. The old Funded entry
point has been removed — a dispute only makes sense once work has started.

Updated submit_milestone()

Now requires InProgress status. Submissions from Funded are rejected, enforcing the
start_milestone() step.

Events

Every state transition emits a Soroban event with a descriptive topic and relevant data
payload, visible in transaction logs.

Docs

docs/soroban-escrow-deployment.md updated with a full ASCII state diagram, function reference
table, authorization model, events table, and error code reference.

Tests

48 contract tests — all passing — covering:

  • Full happy-path lifecycle
  • Every valid transition individually
  • Every invalid transition (wrong state, wrong caller, double-approval, double-fund, etc.)
  • Dispute and refund flows for both client and freelancer
  • Arbiter resolution to either party
  • Terminal state guards (no transitions out of Released / Refunded)
  • Multi-milestone independence

Checklist

  • Invalid state transitions are rejected
  • Only authorized parties can perform transitions
  • Contract tests cover every valid/invalid transition path (48 tests, 0 failures)
  • Events emitted for each transition
  • Dispute and refund flows handled securely

closes #189

…mina-eX#189)

- Add InProgress state to MilestoneStatus enum (Funded → InProgress → Submitted)
- Add start_milestone() function (client-only, Funded → InProgress)
- Update submit_milestone() to require InProgress state
- Update refund() to allow both client and freelancer to initiate
- Update dispute() to accept InProgress | Submitted | Approved states
- Emit events for every state transition (init/fund/start/submt/aprov/cnfrm/relse/rfund/dispt/rslve/expir)
- Add 48 contract tests covering all valid and invalid transition paths
- Update docs/soroban-escrow-deployment.md with state diagram, function reference,
  authorization model, events table, and error codes
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.

[Feature]: Soroban Milestone Escrow State Machine

1 participant