ETHCrowdfundBase.sol#_processContribution - Possible DoS on finalization of crowdfund under certain conditions #119
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
edited-by-warden
insufficient quality report
This report is not of sufficient quality
M-07
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sponsor acknowledged
Technically the issue is correct, but we're not going to resolve it for XYZ reasons
Lines of code
https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/crowdfund/ETHCrowdfundBase.sol#L196-L273
Vulnerability details
Impact
There is a check inside
_processContribution
, which checksif (votingPower == 0)
and reverts if true.Now let's see how we can force it to revert.
If
maxTotalContributions == minTotalContributions
andexchangeRateBps < 1e4
, we can force a rounding down to 0, whentotalContributions = maxTotalContribtuions - 1
.Let's take a look at an example:
Note that this is allowed:
minTotalContributions = 10e18
maxTotalContributions = 10e18
exchangeRateBps = 0.5e4
5e18
to the crowdfund.3e18
to the crowdfund.2e18
is needed to finalize the crowdfund.2e18
, so the crowdfund can be finalized, but is front ran by Charlie (malicious).contribute
with2e18 - 1
.totalContributions
becomes10e18 - 1
, so1 wei
is needed to finalize the crowdfund.contribute
gets executed. She gets refunded2e18 - 1
(since only1 wei
is needed for finalization) .So
amount = 1
8. This line is hit:
Calculating this we get:
(1 * 0.5e4) / 1e4 = 0.5
which rounds down to 0.7. Then we hit the next line:
We will always force a revert here, no matter what original amount is sent, since we refund the excess.
8. A host attempts to call
finalize
, but it reverts because of this:Keep in mind that
minTotalContributions
,maxTotalContributions
andexchangeRateBps
cannot be changed after creation of the crowdfund.Users will be able to call
refund
only after the crowdfund isLost
.The DoS will last as long as the
duration
of the crowdfund. Ifduration = 14 days
, then the users will recover their funds after 14 days.Note that if
emergencyDisabled = true
, the DAO won't be able to retrieve their funds throughemergencyExecute
and the users will have to wait until the crowdfund is lost.Proof of Concept
Paste the following inside
test/crowdfund/InitialETHCrowdfund.t.sol
in contractInitialETHCrowdfundTest
and runforge test --mt test_dosOnFinalizationWhenReachingTheMaxTotalContributions -vvvv
Tools Used
Manual Review
Foundry
Recommended Mitigation Steps
Enforce the constraint to be more strict:
Assessed type
DoS
The text was updated successfully, but these errors were encountered: