Closed code423n4 closed 1 year ago
GalloDaSballo marked the issue as duplicate of #182
GalloDaSballo marked the issue as not a duplicate
GalloDaSballo changed the severity to QA (Quality Assurance)
L
GalloDaSballo marked the issue as grade-c
Great report, but need more!
Lines of code
https://github.com/code-423n4/2023-01-drips/blob/main/src/Splits.sol#L143-L170
Vulnerability details
Impact
In
Splits._split()
, the splitted amounts for each receivers are calculated based on theirweight
s.But if the
collectableAmt * weight
of a receiver is lower than_TOTAL_SPLITS_WEIGHT
, then the splitted amount of tokens could be zero whencollectableAmt * (splitsWeight - currReceivers[i].weight) / _TOTAL_SPLITS_WEIGHT == collectableAmt * splitsWeight / _TOTAL_SPLITS_WEIGHT
. It can easily happen when the user is in the first place of thecurrReceivers
list.Since the calculation depends on the cumulative
weight
s and thecurrReceivers
list is ordered by userID, the splitted result depends on the order of userIDs. The 'less splitted' amount returns to the user in the next order, as thesplitsWeight
has been increased butsplitAmt
hasn't.In addition, the
DripsHub.split(), receiveDrips(), squeezeDrips()
functions are callable by anyone.As a result, an attacker can easily steal splits from a small-portion splits receiver account by calling
receiveDrips()
,squeezeDrips()
properly to fill modest amount of splittables, then callingsplit()
to steal the 'less-splitted' amount.Proof of Concept
Check that the splitted result is affect by the order of
splitsReceivers
Anyone can attack a low-weight account by calling
receiveDrips()
,squeezeDrips()
andsplit()
fromDripsHub
. If the attacker is the next receiver in theSplitsReceiver
list, it would result in draining splitted amounts.Tools Used
Foundry
Recommended Mitigation Steps
You could add
minSplitAmt
as a splits configuration parameter, so that splits configurators can protect small-portion splits receivers by setting a lower bound on the splitted amount each time.