Submitted by DarkTower, also found by 0xJoyBoy03, smbv-1923, d3e4, 0xlemon, trachev, aua_oo7, Afriauditor, Aymen0909, FastChecker, Dots, AgileJune, leegh, Tripathi, turvy_fuzz, GoSlang, McToady, zhaojie, radin100, yotov721, y4y, 0xkeesmark, 0xRiO, gesha17, iberry, 0xmystery, sammy, Fitro, Greed, 0xJaeger, wangxx2026, dd0x7e8, yvuchev, Abdessamed, Daniel526, kR1s, n1punp, AcT3R, SoosheeTheWise, valentin_s2304, btk, pa6kuda, Al-Qa-qa, asui, dvrkzy, crypticdefense, marqymarq10, DanielTan_MetaTrust, and Krace
Any fee claim by the fee recipient lesser than the accrued internal accounting of the yieldFeeBalance is lost and locked in the PrizeVault contract with no way to pull out the funds.
The claimYieldFeeShares allows the yieldFeeRecipient fee recipient to claim fees in yields from the PrizeVault contract. The claimer can claim up to the yieldFeeBalance internal accounting and no more. The issue with this function is it presents a vulnerable area of loss with the _shares argument in the sense that if the accrued yield fee shares is 1000 shares and the claimer claims only 10, 200 or even any amount less than 1000, they forfeit whatever is left of the yieldFeeBalance (e.g if you claimed 200 and hence, got minted 200 shares, you lose the remainder 800 because it wipes the yieldFeeBalance 1000 balance; whereas, they only minted 200 shares).
Lets see a code breakdown of the vulnerable claimYieldFeeShares function:
This line of the function caches the total yield fee balance accrued in the contract and hence, the fee recipient is entitled to (e.g 100).
This next line of code enforces a comparison check making sure the claimer cannot grief other depositors in the vault because the claimant could, for example, try to claim and mint 150 shares; whereas, they are only entitled to 100.
This line of code subtracts the cached total yield fee balance from the state yield fee balance (e.g 100 - 100). So if say Bob, the claimant, tried to only mint 50 shares at this point in time with the _shares argument, the code wipes the entire balance of 100.
And this line of code then mints the specified _shares amount (e.g 50 shares) to Bob:
So what essentially happens is:
Heres a POC for this issue. Place the testUnclaimedFeesLostPOC function inside the PrizeVault.t.sol file and run the test.
Foundry
Adjust the claimYieldFeeShares to only deduct the amount claimed/minted:
trmid (PoolTogether) confirmed and commented:
