Christmas Dinner

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

changeParticipationStatus() does not verify if msg.sender had made deposit

Summary

The changeParticipationStatus() function contains a critical vulnerability that allows users to manipulate their participation status without having made any deposits. This can lead to unauthorized participation in the Christmas dinner event and potentially disrupt the event planning.

Vulnerability Details

The vulnerability exists because the function doesn't verify whether the user has actually made any deposits (either in ERC20 tokens or ETH) before allowing them to set their participation status to true.

Current implementation:

function changeParticipationStatus() external {
if(participant[msg.sender]) {
participant[msg.sender] = false;
} else if(!participant[msg.sender] && block.timestamp <= deadline) {
participant[msg.sender] = true; // <- Vulnerable line
} else {
revert BeyondDeadline();
}
emit ChangedParticipation(msg.sender, participant[msg.sender]);
}

Attack scenario:

  1. An attacker can call changeParticipationStatus() before the deadline

  2. They become a participant without any financial commitment

  3. They can potentially become the host through changeHost() since the only requirement is being a participant

  4. As a host, they could then:

    • Withdraw all funds using the withdraw() function

    • Manipulate the event planning

    • Prevent legitimate participants from getting refunds by changing the host

PoC

// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
contract ChristmasDinnerExploit {
ChristmasDinner target;
constructor(address _target) {
target = ChristmasDinner(_target);
}
function exploit() external {
// Become participant without any deposit
target.changeParticipationStatus();
// Verify we are now a participant
require(target.getParticipationStatus(address(this)), "Failed to become participant");
}
}

Recommendations

Add balance checks before allowing participation status changes:

function changeParticipationStatus() external {
if(participant[msg.sender]) {
participant[msg.sender] = false;
} else if(!participant[msg.sender] && block.timestamp <= deadline) {
// Check if user has made any deposits
require(
balances[msg.sender][address(i_WETH)] > 0 ||
balances[msg.sender][address(i_WBTC)] > 0 ||
balances[msg.sender][address(i_USDC)] > 0 ||
etherBalance[msg.sender] > 0,
"Must deposit funds to participate"
);
participant[msg.sender] = true;
} else {
revert BeyondDeadline();
}
emit ChangedParticipation(msg.sender, participant[msg.sender]);
}
Updates

Lead Judging Commences

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

Deposit function lacks functionality

Support

FAQs

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