Normally, when computing total shares for winners, totalWinnerShares should represent the sum of current winners’ shares only once per finalization.
The _getWinnerShares() function keeps adding to totalWinnerShares every time it’s called, without resetting it to zero. This means that multiple invocations — either intentionally or via setWinner() or later calls — will keep increasing the total beyond its real value.
Likelihood:
Occurs whenever _getWinnerShares() is called more than once (e.g., if setWinner() is called again by mistake or another internal function reuses it).
Can also occur during testing or maintenance where the function is re-run to validate totals, unintentionally inflating results.
Impact:
Impact 1: Inflated totalWinnerShares causes underpayment to winners, since each winner’s share is calculated as Math.mulDiv(shares, vaultAsset, totalWinnerShares) — with a higher denominator reducing payouts.
Impact 2: Repeated calls create inconsistent accounting and possible loss of trust in payout correctness, especially if administrative or off-chain scripts trigger this function multiple times.
Observed Effect:
After two calls, totalWinnerShares becomes roughly 2× its correct value, skewing winner withdrawal amounts.
Explanation: Resetting totalWinnerShares at the start of _getWinnerShares() ensures the total reflects the current, accurate state of all winner shares. Without this, repeated or unintended calls will keep compounding totals. This fix maintains consistent and fair reward calculation.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.