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: 67/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
A yield fee recipient calls the claimYieldFeeShares()
function to claim yield liquidation fees from the PrizeVault. The recipient specifies as input the number of shares he wants to claim, however regardless of the amount specified the function always resets the yield fee balance to 0. So, unless the yield fee recipient always calls the function with the exact amount he will lose fees.
Yield fees are accumulated on token liquidations in the prize vault. Each liquidation contributes a percentage to the yieldFeeBalance
.
When enough fees are accumulated, the yield fee recipient can withdraw them. He does so through the claimYieldFeeShares()
function:
https://github.com/code-423n4/2024-03-pooltogether/blob/main/pt-v5-vault/src/PrizeVault.sol#L611
function claimYieldFeeShares(uint256 _shares) external onlyYieldFeeRecipient { if (_shares == 0) revert MintZeroShares(); uint256 _yieldFeeBalance = yieldFeeBalance; if (_shares > _yieldFeeBalance) revert SharesExceedsYieldFeeBalance(_shares, _yieldFeeBalance); yieldFeeBalance -= _yieldFeeBalance; _mint(msg.sender, _shares); emit ClaimYieldFeeShares(msg.sender, _shares); }
As we can see the receiver speicifies a _shares
input parameter for the amount of shares he wants to receive. These shares are minted to the msg.sender
. However regardless of this amount the yieldFeeBalance is reset to 0:
yieldFeeBalance -= _yieldFeeBalance;
This means that input parameter _shares
must always match yieldFeeBalance to prevent loss of funds. Even if the recipient tries to match variable, liquidation transactions that frontrun the claimYieldFeeShares() transaction will cause loss of funds.
Manual Review
The correct calucation should be:
yieldFeeBalance -= _shares;
This will accurately reflect the shares minted to the user.
Math
#0 - c4-pre-sort
2024-03-11T21:48:03Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-03-11T21:48:09Z
raymondfam marked the issue as duplicate of #10
#2 - c4-pre-sort
2024-03-13T04:38:21Z
raymondfam marked the issue as duplicate of #59
#3 - c4-judge
2024-03-15T07:39:11Z
hansfriese marked the issue as satisfactory