Skip to content

fix: enforce campaign end_time in donate() (closes #5) - #49

Merged
P3az3 merged 1 commit into
MillestoneX:mainfrom
Carlys17:fix/issue-5-donate-end-time-enforcement
Jul 23, 2026
Merged

fix: enforce campaign end_time in donate() (closes #5)#49
P3az3 merged 1 commit into
MillestoneX:mainfrom
Carlys17:fix/issue-5-donate-end-time-enforcement

Conversation

@Carlys17

@Carlys17 Carlys17 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the security gap where donate() did not enforce campaign.end_time. Donations could continue past the deadline until the creator manually called end_campaign().

Closes #5

Changes

campaign/src/lib.rs

  • Added deadline gate inside the Active | GoalReached match arm in donate():
    let now = env.ledger().timestamp();
    match campaign.status {
        CampaignStatus::Active | CampaignStatus::GoalReached => {
            if now >= campaign.end_time {
                panic_with_error!(env, Error::CampaignEnded);
            }
        }
        _ => panic_with_error!(env, Error::CampaignNotActive),
    }
  • Panics with Error::CampaignEnded = 4 (already defined, previously unused in production code)
  • Check positioned after is_frozen but before min_donation_amount — no state mutation on a doomed call
  • Reentrancy lock acquired before the rejection check (no early-return on a held lock)
  • Doc-comment on donate updated to mention the deadline gate

campaign/src/test/negative_path_tests.rs (+4 tests)

  • test_donate_fails_past_deadline_active — Active + past deadline → reject
  • test_donate_fails_past_deadline_goal_reached — GoalReached + past deadline → reject
  • test_donate_fails_at_exact_deadline_boundary — boundary: now == end_time → reject (strict >=)
  • test_donate_succeeds_just_before_deadlinenow == end_time - 1 → succeeds

campaign/src/test/integration_tests.rs (+1 test)

  • test_lifecycle_donate_before_deadline_succeeds — positive lifecycle: donate before deadline accepted

campaign/src/test/invariant_tests.rs (+2 tests)

  • invariant_donate_before_deadline_always_succeeds — positive companion: Active & GoalReached before deadline → succeeds
  • invariant_donate_at_or_past_deadline_always_fails — negative companion: donate(clk >= end_time).is_err() (should_panic with Error::CampaignEnded)

docs/events.md

  • Documented the deadline gate on donation_received event section

Acceptance Criteria Checklist

  • New typed error returned (Error::CampaignEnded = 4) when now >= end_time while status is non-terminal
  • Existing tests pass unchanged
  • Negative-path tests: Active past deadline, GoalReached past deadline, exact boundary
  • docs/events.md and doc-comment on donate updated
  • Reentrancy lock acquired before the rejection check

Implementation Notes

  • Auto-transitioning to Ended status on the first late call was considered but deemed out-of-scope for this security fix. The current approach (reject + panic) is the minimal safe change. A follow-up issue could add auto-transition if desired.
  • Error::CampaignEnded = 4 was already defined in the Error enum but unused in any production code path — this PR puts it to its intended use.

Test Results

All 158 tests pass. Clippy clean. Fmt clean.

merlik787-droi

This comment was marked as off-topic.

@P3az3 P3az3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Carlys17 please remove test snapshots

@P3az3

P3az3 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@Carlys17 resolve conflicts

- Add end_time check in donate() to prevent donations past campaign deadline
- Returns CampaignEnded error when adding funds after end_time
- Add negative path & invariant tests coverage
- Rebase onto upstream main, remove test snapshots
@Carlys17
Carlys17 force-pushed the fix/issue-5-donate-end-time-enforcement branch from e9d327b to aff4375 Compare July 23, 2026 11:40

@P3az3 P3az3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@P3az3
P3az3 merged commit 73ed4af into MillestoneX:main Jul 23, 2026
4 checks 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.

donate does not enforce the campaign end_time

3 participants