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: 24/80
Findings: 2
Award: $132.61
🌟 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#L617
The entire yieldFeeBalance could be permanently lost due to wrong balance update
The issue is in the logic of the claimYieldFeeShares()
function which is intended to allow the yield fee recipient to transfer out yield fee shares. The caller is allowed to specify a non-zero amount of the fee shares to claim and checks that the amount specified is not more than the fee balance else reverts. However, after this check if updates the yield fee balance and then mint the shares for the recipient. The issue here is that the yield fee balance gets updated by the overall balance instead of the amount being claimed:
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 you can see, it minuses the entire balance regardless of the amount of shares to be claimed. This means even when a fee recipient attempts to claim any small amount of fee share, the entire yieldFeeBalance will be permanently lost.
Manual Review
I recommend adding this fix:
- yieldFeeBalance -= _yieldFeeBalance; + yieldFeeBalance -= _shares;
Error
#0 - c4-pre-sort
2024-03-11T21:56:01Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-03-11T21:56:06Z
raymondfam marked the issue as duplicate of #10
#2 - c4-pre-sort
2024-03-13T04:38:34Z
raymondfam marked the issue as duplicate of #59
#3 - c4-judge
2024-03-15T07:38:37Z
hansfriese marked the issue as satisfactory
🌟 Selected for report: Aymen0909
Also found by: 0xmystery, Abdessamed, FastChecker, Giorgio, Tripathi, btk, cheatc0d3, trachev, turvy_fuzz
131.1445 USDC - $131.14
https://github.com/code-423n4/2024-03-pooltogether/blob/main/pt-v5-vault/src/PrizeVault.sol#L493 https://github.com/code-423n4/2024-03-pooltogether/blob/main/pt-v5-vault/src/PrizeVault.sol#L504
The withdraw and redeem operations in PrizeVault are exposed to high slippage returns and could result in a loss for LPs of PrizeVault.
When withdraw or redeem is called, they both work in similar ways in returning the amount to be burnt or received. When all assets are below the debt, the amount returned could vary. However, there is no slippage protection for these operations.
function withdraw( uint256 _assets, address _receiver, address _owner ) external returns (uint256) { uint256 _shares = previewWithdraw(_assets); _burnAndWithdraw(msg.sender, _receiver, _owner, _shares, _assets); return _shares; }
function redeem( uint256 _shares, address _receiver, address _owner ) external returns (uint256) { uint256 _assets = previewRedeem(_shares); _burnAndWithdraw(msg.sender, _receiver, _owner, _shares, _assets); return _assets; }
However, there are no parameters for amountOutMin
or amountInMax
, which are used to prevent slippage. These parameters should be checked to create slippage protections.
https://docs.uniswap.org/contracts/v3/guides/providing-liquidity/decrease-liquidity
Visual Studio Code
There are no parameters for amountOutMin
or amountInMax
, which are used to prevent slippage for varying return amount. These parameters should be checked to create slippage protections.
https://docs.uniswap.org/contracts/v3/guides/providing-liquidity/decrease-liquidity
MEV
#0 - c4-pre-sort
2024-03-11T23:49:31Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-03-11T23:49:37Z
raymondfam marked the issue as duplicate of #90
#2 - c4-pre-sort
2024-03-13T05:09:56Z
raymondfam marked the issue as duplicate of #274
#3 - c4-judge
2024-03-15T08:08:53Z
hansfriese changed the severity to 2 (Med Risk)
#4 - c4-judge
2024-03-15T08:09:01Z
hansfriese marked the issue as satisfactory