PoolTogether - FastChecker'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: 27/80

Findings: 2

Award: $132.61

🌟 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#L611-L622

Vulnerability details

Impact

The recipient of the yieldfee might suffer a loss of the yield fee.

Proof of Concept

The PrizeVault.sol#claimYieldFeeBalance() function is as follows.

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

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

617     yieldFeeBalance -= _yieldFeeBalance;

        _mint(msg.sender, _shares);

        emit ClaimYieldFeeShares(msg.sender, _shares);
    }

As observed in the code snippet on the right, in L617, yieldFeeBalance is initialized to 0 irrespective of the amount of shares to be minted to the yield fee recipient. Therefore, the recipient of the yield fee loses the fee when _shares < _yieldFeeBalance.

Tools Used

Manual Review

Modify the PrizeVault.sol/claimYieldFeeBalance() function as follows.

    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-11T22:14:26Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2024-03-11T22:14:31Z

raymondfam marked the issue as duplicate of #10

#2 - c4-pre-sort

2024-03-13T04:38:39Z

raymondfam marked the issue as duplicate of #59

#3 - c4-judge

2024-03-15T07:38:21Z

hansfriese marked the issue as satisfactory

Findings Information

🌟 Selected for report: Aymen0909

Also found by: 0xmystery, Abdessamed, FastChecker, Giorgio, Tripathi, btk, cheatc0d3, trachev, turvy_fuzz

Labels

bug
2 (Med Risk)
satisfactory
sufficient quality report
:robot:_90_group
duplicate-274

Awards

131.1445 USDC - $131.14

External Links

Lines of code

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

Vulnerability details

Impact

Loss of assets for the affected users.

Proof of Concept

The PrizeVault.sol#withdraw() and PrizeVault.sol#redeem() functions call the PrizeVault.sol#previewWithdraw() and PrizeVault.sol#previewRedeem() functions to calculate the amount of stocks to be burned or assets to be redeemed. When users deposit into PrizeVault they are really depositing into an ERC4626 vault that contributes its yield to the Prize Pool. Therefore, when executing a transaction, the entire assets of PrizeVault can rise or fall at any time depending on the current onchain status according to the stock value of the yield vault.

    function totalAssets() public view returns (uint256) {
        return yieldVault.convertToAssets(yieldVault.balanceOf(address(this))) + _asset.balanceOf(address(this));
    }

Therefore, if PrizeVault's total assets become less than totalDebt, slippage may occur in these functions(previewWithdraw(), previewRedeem()). This slippage is more than what they can accept. In summary, the PrizeVault.sol#withdraw(), PrizeVault.sol#redeem() functions lack slippage control that allows the user to revert if the amount of shares the user redeems is greater than expected or if the amount of assets the user receives is less than expected.

Tools Used

Manual Review

Implement slip control in PrizeVault.sol#withdraw(), PrizeVault.sol#redeem() functions.

Assessed type

Other

#0 - c4-pre-sort

2024-03-11T23:47:36Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2024-03-11T23:47:42Z

raymondfam marked the issue as duplicate of #90

#2 - c4-pre-sort

2024-03-13T05:09:54Z

raymondfam marked the issue as duplicate of #274

#3 - c4-judge

2024-03-15T08:09:17Z

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