feat: Add dispute resolution mechanism for milestones#8
Conversation
Disputed milestones were a dead-end with no way to resolve them. This adds admin-only `resolve_dispute` to settle disputes in favor of either the creator (release funds) or backer (reject + cancel campaign for refunds), along with a `get_dispute_status` query and `DisputeResolved` event for indexer integration. Also fixes stale integration test call sites missing the `submit` bool and `reason` arguments added in prior commits. Closes #2 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughA dispute resolution mechanism for crowdfunding milestones has been implemented, adding admin-only functions to query and resolve disputed milestones with different outcomes: creator approval releases funds and completes campaigns when all milestones are released, while backer approval rejects milestones, cancels campaigns, and enables refunds. Corresponding event, error, and storage types have been added, along with comprehensive tests and snapshot updates. Changes
Sequence Diagram(s)sequenceDiagram
participant Admin as Admin User
participant Contract as Crowdfund Contract
participant Escrow as Escrow Contract
participant Reputation as Reputation Registry
rect rgb(100, 150, 200, 0.5)
Note over Admin,Reputation: ApproveCreator Resolution Path
Admin->>Contract: resolve_dispute(campaign_id, milestone, ApproveCreator)
Contract->>Contract: Load milestone (assert Disputed)
Contract->>Contract: Set milestone status to Released
Contract->>Escrow: release_slot(milestone)
Escrow-->>Contract: Funds released
Contract->>Contract: Check all milestones Released?
alt All milestones released
Contract->>Contract: Mark campaign Completed
Contract->>Reputation: record_campaign_backed(campaign_id)
Reputation-->>Contract: Reputation recorded
end
Contract->>Contract: Emit DisputeResolved(ApproveCreator)
Contract-->>Admin: Success
end
rect rgb(200, 100, 100, 0.5)
Note over Admin,Contract: ApproveBacker Resolution Path
Admin->>Contract: resolve_dispute(campaign_id, milestone, ApproveBacker)
Contract->>Contract: Load milestone (assert Disputed)
Contract->>Contract: Set milestone status to Rejected
Contract->>Contract: Mark campaign Cancelled
Contract->>Contract: Reset refund_progress to 0
Contract->>Contract: Emit DisputeResolved(ApproveBacker)
Contract-->>Admin: Success (refunds now available)
end
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly Related Issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
resolve_dispute(campaign_id, milestone_index, resolution)admin-only function with two resolution paths:ApproveCreator(releases milestone funds) andApproveBacker(rejects milestone, cancels campaign, enables refunds)get_dispute_status(campaign_id, milestone_index)query for checking current milestone dispute stateDisputeResolvedevent with campaign_id, milestone_id, and resolution for indexer integrationsubmitbool andreasonarguments from prior commitsCloses #2
Test plan
test_resolve_dispute_approve_creator— full flow: dispute → resolve for creator → funds released → campaign continuestest_resolve_dispute_approve_backer— full flow: dispute → resolve for backer → milestone rejected → campaign cancelled → refunds processedtest_resolve_dispute_not_disputed_fails— resolving a non-disputed milestone returnsMilestoneNotDisputederrorSummary by CodeRabbit
Release Notes