Skip to content

fix(escrow): deduplicate sponsor contributions to prevent MAX_SPONSORS exhaustion - #175

Open
rafaio1 wants to merge 1 commit into
MergeFi:mainfrom
rafaio1:fix/contribute-dedup-sponsor-139
Open

fix(escrow): deduplicate sponsor contributions to prevent MAX_SPONSORS exhaustion#175
rafaio1 wants to merge 1 commit into
MergeFi:mainfrom
rafaio1:fix/contribute-dedup-sponsor-139

Conversation

@rafaio1

@rafaio1 rafaio1 commented Aug 21, 2026

Copy link
Copy Markdown

Summary

Fixes #139

Problem

contribute() increments escrow.contributor_count on every accepted call and rejects once it hits MAX_SPONSORS (20), but never checks whether the sponsor already has an existing Contribution entry for this issue_id. A single address calling contribute 19 times after the original fund is accepted as 19 separate contribution slots, each counted against the cap. This permanently locks out every other would-be co-funder for that issue_id with TooManySponsors, while the design doc's own framing assumes the cap protects against a large number of different people joining, not one person calling repeatedly.

Additionally, refund() would issue N separate token transfers to the same address instead of one consolidated transfer.

Fix

contribute() now iterates over existing contributions to check if the sponsor already holds a Contribution entry for this issue_id. If found, the new amount is added to the existing entry in place rather than appending a new indexed slot. Only genuinely new sponsors consume a slot against MAX_SPONSORS.

Testing

  • All 36 existing unit tests pass unchanged
  • The fix preserves backward compatibility: existing single-contribution sponsors behave identically
  • Multi-sponsor refund and release logic remain correct since they iterate by index and sum amounts per-entry

Impact

Prevents denial-of-service against crowdfunding participation and reduces unnecessary storage/gas overhead from duplicate contribution entries.

…S exhaustion

A single address could call contribute() repeatedly, each time consuming
a new slot against MAX_SPONSORS (20) and permanently locking out other
would-be co-funders. The cap was intended to bound distinct sponsors, not
contribution calls.

Now contribute() checks whether the sponsor already has an existing
Contribution entry for this issue_id. If so, it adds to that entry in
place rather than appending a new indexed slot. Only genuinely new
sponsors consume a slot against MAX_SPONSORS.

Closes MergeFi#139
@vercel

vercel Bot commented Aug 21, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the chonilius' projects Team on Vercel.

A member of the Team first needs to authorize it.

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.

escrow::contribute lets a single sponsor exhaust MAX_SPONSORS via repeated self-contributions

1 participant