Skip to content

fix: reject set_personal_cap below lifetime_contribution (#441) - #744

Merged
davidmaronio merged 2 commits into
Iris-IV:mainfrom
CHKM001:fix/441-set-personal-cap-lifetime-v2
Aug 6, 2026
Merged

fix: reject set_personal_cap below lifetime_contribution (#441)#744
davidmaronio merged 2 commits into
Iris-IV:mainfrom
CHKM001:fix/441-set-personal-cap-lifetime-v2

Conversation

@CHKM001

@CHKM001 CHKM001 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

PR #441: Reject personal cap below lifetime_contribution

Problem

set_personal_cap_fn did not validate the new cap against the caller's existing lifetime_contribution. A contributor could set their cap to 1 stroop after contributing 1000 XLM, permanently blocking further contributions with no way to raise the cap again.

Fix

Added a validation check in set_personal_cap_fn (src/contributions.rs) that rejects any personal cap value below the caller's current lifetime_contribution:

let lifetime = get_lifetime_contribution(env, campaign_id, &contributor);
if amount < lifetime {
    return Err(Error::ValidationFailed);
}

Setting a cap equal to lifetime_contribution is intentionally allowed — it blocks future contributions without stranding anything, and the contributor can always set a higher cap later.

Tests

Two regression tests in src/tests/test_regressions.rs:

  1. test_set_personal_cap_below_lifetime_contribution_rejected — contributes 1000, asserts cap=500 is rejected, cap=1000 is accepted, cap=2000 is accepted.
  2. test_set_personal_cap_equal_lifetime_blocks_further_contributions — contributes 1000, sets cap to 1000 (equal to lifetime), asserts a subsequent contribution of 1 stroop is rejected with ContributionCapExceeded. This documents the boundary behavior as intentional.

Diff

 src/contributions.rs          |  4 ++++
 src/tests/test_regressions.rs | 61 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

Closes #441

CHKM001 added 2 commits August 5, 2026 22:25
Validate the new personal cap against the caller's existing
lifetime_contribution in set_personal_cap_fn. Setting a cap below what
the contributor has already contributed is rejected with
ValidationFailed, preventing self-freeze with no recovery path.

Two regression tests added:
- Rejects cap below lifetime_contribution
- Asserts cap == lifetime blocks further contributions (boundary test)
Validate the new personal cap against the caller's existing
lifetime_contribution in set_personal_cap_fn. Setting a cap below what
the contributor has already contributed is rejected with
ValidationFailed, preventing self-freeze with no recovery path.

Two regression tests added:
- Rejects cap below lifetime_contribution
- Asserts cap == lifetime blocks further contributions (boundary test)
@davidmaronio

Copy link
Copy Markdown
Contributor

thanks for the clean resubmission, this version is a proper 2 file diff and the guard plus boundary tests are correct. unfortunately #688 was opened earlier for the same fix (issue family #441/#457), has the same guard, and also updates the property test model in test_cap_interactions.rs so the proptest oracle stays in sync with set_personal_cap_fn, which this pr leaves stale. closing in favor of #688. happy to see you on another open issue.

@davidmaronio davidmaronio reopened this Aug 6, 2026
@davidmaronio
davidmaronio merged commit 8a94503 into Iris-IV:main Aug 6, 2026
9 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.

[Bug] set_personal_cap allows setting cap below current lifetime_contribution — contributor self-freezes future contributions with no way out

2 participants