Platform: Code4rena
Start Date: 04/03/2024
Pot Size: $36,500 USDC
Total HM: 9
Participants: 80
Period: 7 days
Judge: hansfriese
Total Solo HM: 2
Id: 332
League: ETH
Rank: 63/80
Findings: 1
Award: $1.47
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: DarkTower
Also found by: 0xJaeger, 0xJoyBoy03, 0xRiO, 0xkeesmark, 0xlemon, 0xmystery, Abdessamed, AcT3R, Afriauditor, AgileJune, Al-Qa-qa, Aymen0909, Daniel526, DanielTan_MetaTrust, Dots, FastChecker, Fitro, GoSlang, Greed, Krace, McToady, SoosheeTheWise, Tripathi, asui, aua_oo7, btk, crypticdefense, d3e4, dd0x7e8, dvrkzy, gesha17, iberry, kR1s, leegh, marqymarq10, n1punp, pa6kuda, radin100, sammy, smbv-1923, trachev, turvy_fuzz, valentin_s2304, wangxx2026, y4y, yotov721, yvuchev, zhaojie
1.4652 USDC - $1.47
https://github.com/code-423n4/2024-03-pooltogether/blob/main/pt-v5-vault/src/PrizeVault.sol#L611 https://github.com/code-423n4/2024-03-pooltogether/blob/main/pt-v5-vault/src/PrizeVault.sol#L617
Whenever onlyYieldFeeRecipient
calls claimYieldFeeShares(uint256 _shares)
,
if _shares < total shares accrued from yield fee balance then there will be
loss of yieldFeeBalance and that yieldFeeBalance could never be claimed back.
There is no check in claimYieldFeeShares()
that how many shares the claimer
wants to claim so according to that yieldFeeBalance
should get subtracted,
but here whole yieldFeeBalance gets subtracted without checking how many shares
the claimer wants to claim
function testClaimFeeBalance_Bug() public { vault.setYieldFeePercentage(1e8); // 10% vault.setYieldFeeRecipient(bob); assertEq(vault.totalDebt(), 0); // make an initial deposit underlyingAsset.mint(alice, 1e18); vm.startPrank(alice); underlyingAsset.approve(address(vault), 1e18); vault.deposit(1e18, alice); vm.stopPrank(); assertEq(vault.totalAssets(), 1e18); assertEq(vault.totalSupply(), 1e18); assertEq(vault.totalDebt(), 1e18); // mint yield to the vault and liquidate underlyingAsset.mint(address(vault), 1e18); vault.setLiquidationPair(address(this)); uint256 maxLiquidation = vault.liquidatableBalanceOf(address(underlyingAsset)); uint256 amountOut = maxLiquidation / 2; uint256 yieldFee = (1e18 - vault.yieldBuffer()) / (2 * 10); // 10% yield fee + 90% amountOut = 100% console.log("the generated fee from liquidation ",yieldFee); vault.transferTokensOut(address(0), bob, address(underlyingAsset), amountOut); assertEq(vault.totalAssets(), 1e18 + 1e18 - amountOut); // existing balance + yield - amountOut assertEq(vault.totalSupply(), 1e18); // no change in supply since liquidation was for assets assertEq(vault.totalDebt(), 1e18 + yieldFee); // debt increased since we reserved shares for the yield fee // Claiming yield fee shares vm.startPrank(bob); console.log("Before claiming Yield fee balance ",vault.yieldFeeBalance()); vault.claimYieldFeeShares(yieldFee/2); // claiming only 1/2 of the yieldFee share and remaining half of the shares. // Half of the shares yet to be claimed assertEq(vault.totalDebt(), vault.totalSupply()); // As we can see yieldFeeBalance became zero while claiming only 1/2 of the YieldFeeShare. // But in original yieldFeeBalance should be vault.yieldFeeBalance()/2 but due to bug vault.yieldFeeBalance() becomes zero. // Thus losing 1/2 of the yieldFeeBalance. assertEq(vault.yieldFeeBalance(), 0); console.log("After claiming half of the shares , 1/2 of the yield fee balance should be remaining"); console.log("the yield fee balance",vault.yieldFeeBalance()); console.log("The yield fee balance got 0 instead of being half"); vm.stopPrank(); }
Manual Review
While claiming claimYieldFeeShares()
it should be checked how many amount of shares the claimer wants to claim rather than subtracting whole yieldFeeBalance.
Other
#0 - c4-pre-sort
2024-03-11T23:08:56Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-03-11T23:09:02Z
raymondfam marked the issue as duplicate of #10
#2 - c4-pre-sort
2024-03-13T04:38:46Z
raymondfam marked the issue as duplicate of #59
#3 - c4-judge
2024-03-15T07:37:46Z
hansfriese marked the issue as satisfactory