refunds in contribute() may brick crowdfunds from becoming won/finalized and minTotalContributions will never be reached #135
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate-127
edited-by-warden
insufficient quality report
This report is not of sufficient quality
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/crowdfund/InitialETHCrowdfund.sol#L164
Vulnerability details
Impact
When a members contributes to a crowdfund via contribute(), the user donates a specified amount of eth to the crowdfund contract. The amount must be above the minContribution per user and lower than the maxContribution per user. If there are multiple members, the total amount of contributions must never exceed the
maxTotalContributions
and a crowdfund is considered sucessfull when the total amount of contributions is more than the minTotalContributions value.When contributing, if a user donates an eth amount which takes the
totalContributions
above themaxTotalContributions
, the user is refunded the eth differece and the amount donated is adjusted to an amount that just takes thetotalContributions
to be equal to themaxTotalContributions
. It is possible that during the refund process, the adjusted contribution amount for the user will be below theminContribution
per user. And this will cause a revert as seen hereLets have a scenario where minTotalContributions is 4.5 eth, maxTotalContributions is 5 eth, minContribution per user is 2 eth. If two members donate 2 eth each, the totalContributions becomes 4 eth. 0.5 eth is left to make the contributions up to minTotalContributions so that the crowdfund can be considered won and finalized. A third user proceeds to donate 2 eth, which is the minContribution per user. The system takes the 2 eth and because 2 eth will take the totalContributions up to 6 eth, the user gets refunded 1 eth so that totalContributions is eq to the maxTotalContributions of 5 eth. The third user contribution amount becomes 1 eth, but since 1 eth is not accepted because it is below minContribution (2 eth) per user the function reverts. This leaves the party crowdfund in a precarious situation as :
minTotalContributions
will never be reached.Note: the comments here says that it recognizes a similar scenario where "crowdfunds may not reach
maxTotalContributions
" and suggests that the members wait till the crowdfund is expired so that the host can finalize but what of the case whereminTotalContributions
is also never reached like my scenario describes? This will mean that the finalization will not be possible by the host and the crowdfund will be lost unfairly.Proof of Concept
I wrote a test POC to illustrate this bug. See it below:
NOTE: paste code below into new file in the
test/crowdfund
folder and run withforge test --mt test_Case_02
Tools Used
manual review, foundry
Recommended Mitigation Steps
check that
amount > minContribution
before the refund. This way, the modified amount after refund is done will allow formaxTotalContributions === totalContributions
.Assessed type
DoS
The text was updated successfully, but these errors were encountered: