MyCut

First Flight #23
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

Wrong Math implementation in `pot::closePot` function causing locking of funds and users Recieve fewer rewards than expected

Summary

The formula of calculating claimantCut in pot::closePot function is not correct which lead to lock of funds in the pot contract and claimants Recieve fewer rewards than expected

https://github.com/Cyfrin/2024-08-MyCut/blob/946231db0fe717039429a11706717be568d03b54/src/Pot.sol#L57C12-L57C86

Vulnerability Details

when the owner of the contest call pot::closePot function the remmaning rewards in the contract are divided two things happen

  1. the owner recieve the ownerCut which is 10% of the remmainingRewards

  2. the rest of the remmainingRewards after subtracting ownerCut is distributed Equally among climants.The issue occur when the contract calculate the claimantCut it calculate it based on players in the contest not the claimants therefore there is some tokens locked in the pot contract
    Because when you try to call pot::closePot again which the only way to withdraw the remainingRewards it will revert since there no enough balance to deduct the ownerCut again and transfer rest to claimants

  • Use the following POC in TestMyCut.t.sol

    function testOwnerCutFormulaIsWrong() public mintAndApproveTokens {
    vm.startPrank(user);
    rewards = [500, 500];
    totalRewards = 1000;
    contest = ContestManager(conMan).createContest(
    players,
    rewards,
    IERC20(ERC20Mock(weth)),
    totalRewards
    );
    ContestManager(conMan).fundContest(0);
    vm.stopPrank();
    vm.startPrank(player1);
    Pot(contest).claimCut();
    vm.stopPrank();
    uint256 claimantBalanceBefore = ERC20Mock(weth).balanceOf(player1); //500
    assertEq(claimantBalanceBefore, 500);
    vm.warp(91 days);
    vm.startPrank(user);
    ContestManager(conMan).closeContest(contest);
    vm.expectRevert();
    // trying to call the function again to claim remaining tokens but but the call fails due to insufficent balance in the pot
    ContestManager(conMan).closeContest(contest);
    vm.stopPrank();
    // Here the balance of the claimant should be 500+450=950 since there is one Claimant
    //But since the formula is calculating the claimantCut on players not claimants the balance will be 500+225=725
    uint256 claimantBalanceAfter = ERC20Mock(weth).balanceOf(player1); //500+225=725
    assertEq(claimantBalanceAfter, claimantBalanceBefore + 225);
    // the balance of the pot should equal 0 after calling closeContest
    //1.10% goes to the owner as ownerCut
    //2.the rest goes to the claimants equally
    // this prove that the contestBalance is bigger than 0 after calling closeContest(formula is wrong)
    //remmaining = 950-725=225 (will be stuck in the pot )
    assertEq(ERC20Mock(weth).balanceOf(address(contest)), 225);
    }

Impact

  1. Locking some tokens in pot contract

  2. claimants will recieve fewer amount than excpected

Tools Used

Manual Review + foundry

Recommendations

  • implement the following formula in pot::closePot function to calculate claimantsCut

function closePot() external onlyOwner {
if (block.timestamp - i_deployedAt < 90 days) {
revert Pot__StillOpenForClaim();
}
if (remainingRewards > 0) {
uint256 managerCut = remainingRewards / managerCutPercent;
i_token.transfer(msg.sender, managerCut);
- uint256 claimantCut = (remainingRewards - managerCut) / i_players.length;
+ uint256 claimantCut = (remainingRewards - managerCut) / claimants.length;
for (uint256 i = 0; i < claimants.length; i++) {
_transferReward(claimants[i], claimantCut);
}
}
}
Updates

Lead Judging Commences

equious Lead Judge 11 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Incorrect distribution in closePot()

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.