code-423n4 / 2021-06-pooltogether-findings

0 stars 0 forks source link

Awarding takes reserve fee several times #85

Closed code423n4 closed 3 years ago

code423n4 commented 3 years ago

Handle

cmichel

Vulnerability details

The PrizePool.captureAwardBalance function takes fees repeatedly on the same interest. One would expect unaccountedPrizeBalance to be 0 in any repeated calls, but it's not.

Assume the following example scenario with a 10% reserve fee:

Impact

Instead of taking a reserve fee f (0 <= f < 1.0 = 100%), a higher fee of f / (1 - f) can be taken by repeated calls to captureAwardBalance. The pool creator (or reserve registry owner) can even use this with a high reserve fee (~99%) to rug the entire pool investments by inflating the reserveTotalSupply to almost any arbitrary value and later redeeming everything using withdrawReserve.

Recommended Mitigation Steps

When determining the amount to take a fee on (unaccountedPrizeBalance), one needs to take into account not only the after-fee amount (_currentAwardBalance) but the pre-fee amount. This probably requires tracking another variable.

asselstine commented 3 years ago

Note for self: I don't think this is an issue; I think cmichel missed the fact that _tokenTotalSupply() includes the reserve fee. So the reserve is accounted for, albeit obscurely. Might need a test for this one though.

aodhgan commented 3 years ago

This has been found to be a non-issue. See PR (https://github.com/pooltogether/pooltogether-pool-contracts/pull/317)

As @asselstine alluded to - the reserve balance is included within the result from _tokenTotalSupply() so reserve is not captured twice.

dmvt commented 3 years ago

Closing per sponsor's explanation