PoolTogether - 0xJaeger's results

General Information

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

PoolTogether

Findings Distribution

Researcher Performance

Rank: 73/80

Findings: 1

Award: $1.47

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

1.4652 USDC - $1.47

Labels

bug
3 (High Risk)
satisfactory
sufficient quality report
:robot:_10_group
duplicate-59

External Links

Lines of code

https://github.com/code-423n4/2024-03-pooltogether/blob/main/pt-v5-vault/src/PrizeVault.sol#L617

Vulnerability details

Impact

When yieldFeeRecipient calls the claimYieldFeeShares() function with an amount of shares that is less than the yieldFeeBalance, the yieldFeeBalance will be reset to 0. As a result, the difference between the claimed shares and the yieldFeeBalance will effectively be lost.

Proof of Concept

Here is a coded POC which can be directly pasted in Liquidate.t.sol

import {console2} from "forge-std/Test.sol";
function testClaimYieldFeeShares_withdrawPartial() public {
        vault.setYieldFeePercentage(1e8); // 10% fee
        vault.setYieldFeeRecipient(bob);
        vault.setLiquidationPair(address(this));

        // liquidate some yield
        underlyingAsset.mint(address(vault), 1e18);
        uint256 amountOut = vault.liquidatableBalanceOf(address(underlyingAsset));
        assertGt(amountOut, 0);

        vault.transferTokensOut(address(0), alice, address(underlyingAsset), amountOut);
        uint256 yieldFeeBalanceBefore = vault.yieldFeeBalance();
        console2.log("YieldFeeBalance before claim: ", yieldFeeBalanceBefore);
        // YieldFeeBalance before claim: 99999999999900000

        vm.prank(bob);
        vault.claimYieldFeeShares(yieldFeeBalanceBefore / 3);
        console2.log("Balance of Bob after claim: ", vault.balanceOf(bob));
        // Balance of Bob after claim: 33333333333300000

        uint256 yieldFeeBalanceAfter = vault.yieldFeeBalance();
        console2.log("YieldFeeBalance after claim: ", yieldFeeBalanceAfter);
        // YieldFeeBalance after claim: 0
        // The yieldFeeBalanceAfter is 0 after the claim, but should be 66666666666600000 (yieldFeeBalanceBefore - yieldFeeBalanceBefore / 3)
    }

Tools Used

Manual Analysis

The error is caused from a logical error inside the claimYieldFeeShares() here is the suggested patch to fix this error in PrizeVault.sol:

 function claimYieldFeeShares(uint256 _shares) external onlyYieldFeeRecipient {
        if (_shares == 0) revert MintZeroShares();

        uint256 _yieldFeeBalance = yieldFeeBalance;
        if (_shares > _yieldFeeBalance) revert SharesExceedsYieldFeeBalance(_shares, _yieldFeeBalance);

-       yieldFeeBalance -= _yieldFeeBalance;
+       yieldFeeBalance -= _shares;

        _mint(msg.sender, _shares);

        emit ClaimYieldFeeShares(msg.sender, _shares);
    }

Assessed type

Other

#0 - c4-pre-sort

2024-03-11T21:41:40Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2024-03-11T21:41:45Z

raymondfam marked the issue as duplicate of #10

#2 - c4-pre-sort

2024-03-13T04:38:15Z

raymondfam marked the issue as duplicate of #59

#3 - c4-judge

2024-03-15T07:40:27Z

hansfriese marked the issue as satisfactory

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