Christmas Dinner

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

Premature Withdrawal Vulnerability in `ChristmasDinner::withdraw`

Summary

The withdraw function allows the host to transfer all ERC20 token balances from the contract to their wallet. However, the implementation does not include a check to ensure the deadline has passed before allowing withdrawals. This oversight could result in the host depleting the contract’s funds prematurely, leaving no tokens available for participant refunds.

Vulnerability Details

The function transfers the entire balance of whitelisted ERC20 tokens from the contract to the host’s address.
There is no check to ensure the deadline has passed, allowing the host to invoke this function at any time.
This premature withdrawal can result in depriving participants of their ability to receive refunds and undermining trust in the contract’s fairness and reliability.

PoC

Append the following code snippet at the end of function test_withdrawAsHost() in the test suite:

uint deadlineTime = cd.deadline();
console.log(deadlineTime, block.timestamp);

Run the test forge test --mt test_withdrawBeforeDeadline -vvvv and observe the log results.

Impact

This vulnerability allows the host to withdraw all contract funds prematurely, resulting in:

  • Denial of refunds to participants who wish to withdraw before the event.

  • Financial losses for participants who trusted the contract to hold their contributions securely.

  • Potential exploitation by malicious/greedy host, breaking the decentralization aspect of the protocol.

Tools Used

Manual code review, Foundry

Recommendations

Add a condition to ensure that withdrawals can only occur after the deadline has passed:

function withdraw() external onlyHost {
+ ---> require(block.timestamp > deadline, "Cannot withdraw before the deadline");
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 about 1 year 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.

Give us feedback!