Christmas Dinner

First Flight #31
Beginner FriendlyFoundrySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

Lack of a deadline check allows the host to withdraw funds prematurely, bypassing the refund period

Summary

The ChristmasDinner::withdraw function lacks a deadline check which allows the host to withdraw funds prematurely, bypassing the refund period.

Vulnerability Details

There is a missing deadline check in the ChristmasDinner::withdraw function that allows the host to withdraw funds at any time, regardless of whether the event deadline has passed. The host can just drain all the funds that were deposited by participants, making it impossible for them to claim refunds before the deadline passes.

POC

Add the following code to ChristmasDinnerTest::test_withdrawAsHost :

function test_withdrawAsHost() public {
// deadline is set to 7 days in setUp() by default
// simulate that 3 days have passed => 4 days left
+ vm.warp(block.timestamp + 3 days);
uint256 wethAmount;
uint256 wbtcAmount;
uint256 usdcAmount;
vm.startPrank(user1);
cd.deposit(address(wbtc), 0.5e18);
wbtcAmount += 0.5e18;
cd.deposit(address(weth), 2e18);
wethAmount += 2e18;
vm.stopPrank();
vm.startPrank(user2);
cd.deposit(address(usdc), 2e18);
usdcAmount += 2e18;
cd.deposit(address(wbtc), 1e18);
wbtcAmount += 1e18;
vm.stopPrank();
vm.startPrank(deployer);
cd.withdraw();
vm.stopPrank();
assertEq(wbtc.balanceOf(deployer), wbtcAmount);
assertEq(weth.balanceOf(deployer), wethAmount);
assertEq(usdc.balanceOf(deployer), usdcAmount);
}

In the ChristmasDinnerTest::test_setUp⁣ a deadline is set for 7 days. Then, in the ChristmasDinnerTest::test_withdrawAsHost the test simulates that 3 days have passed since the beginning of the fundraising event. Although there are 4 days left, the host still withdraws the funds. Now, if a participant decides to refund, they will not receive their deposits back.

Impact

  1. Participants lose their deposits.

  2. Participants lose their trust in the protocol.

  3. The host can drain all deposited funds before the deadline passes.

  4. The protocol's behavior of securing funds for the event until the deadline is flawed.

Tools Used

  • Manual review

  • Foundry

Recommendations

Add a check to the withdraw function to ensure that it can only be called after the deadline has passed.

Add an appropriate event to revert with as well.

+ error DeadlineNotReached();
function withdraw() external onlyHost {
+ if (block.timestamp <= deadline) {
+ revert DeadlineNotReached();
+ }
address _host = getHost();
i_WETH.safeTransfer(_host, i_WETH.balanceOf(address(this)));
i_WBTC.safeTransfer(_host, i_WBTC.balanceOf(address(this)));
i_USDC.safeTransfer(_host, i_USDC.balanceOf(address(this)));
}
Updates

Lead Judging Commences

0xtimefliez Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

withdraw is callable before deadline ends

0xtimefliez Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

withdraw is callable before deadline ends

Support

FAQs

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