Christmas Dinner

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

Host can change status to a non-participant before the deadline end

Summary

In the ChristmasDinner contract a host can change his/her status to a non-participant for the event.

Vulnerability Details

The vubrability is exposed when someone that is a host calls the changeParticipationStatus function that changes the his/her participant status(when the first if statement in the function is entered). This contradicts the logic in the changeHost function that states that the host must attend the event when chaning ownership.

function changeParticipationStatus() external {
if (participant[msg.sender]) {
participant[msg.sender] = false;
} else if (!participant[msg.sender] && block.timestamp <= deadline) {
participant[msg.sender] = true;
} else {
revert BeyondDeadline();
}
emit ChangedParticipation(msg.sender, participant[msg.sender]);
}
function changeHost(address _newHost) external onlyHost {
if (!participant[_newHost]) {
revert OnlyParticipantsCanBeHost();
}
host = _newHost;
emit NewHost(host);
}

Impact

The vulnerability exposes a situation where the person is not planning to attend the event but is still marked as the host. This means that noone except him/her can withdraw the funds in the contract and take over the organization and expenses. In this case the host needs to transfer the rights to another person but since he/she is not attending the event he/she could stopped following the events around it.

Tools Used

  • Manual Review

  • Foundry testing

POC

function test_hostCanChangeStatusToNotAttendingTheEvent()
public
{
// We add an user as a attender to the event
vm.startPrank(user2);
cd.changeParticipationStatus();
// We check the user is now attending the evet
assertEq(cd.getParticipationStatus(user2), true);
vm.stopPrank();
// We change the host of the event to the newly added user
vm.startPrank(deployer);
cd.changeHost(user2);
// We verify the host is now user2
assertEq(cd.getHost(), user2);
vm.stopPrank();
vm.startPrank(user2);
//We change the status of the user to not attending the event
cd.changeParticipationStatus();
//This dose not follow the logic defined in 'changeHost' function
//as user 2 is now the host but is not attending the event
assertEq(cd.getParticipationStatus(user2), false);
assertEq(cd.getHost(), user2);
vm.stopPrank();
}

Recommendations

We can add a check in the changeParticipationStatus function to validate that we are not changing the host user to a non-participant. We do this check at the top of the function to avoid gas consumption by modifying storage values. We also verify that this is done before the deadline as we know that after the deadline is passed we can still change the host but this needs to be done outside of the contract, we might still want to mark that the host is no longer the one stated in the contract.

function changeParticipationStatus() extrnal {
if (
msg.sender == host &&
participant[host] &&
block.timestamp <= deadline
) {
//Added HostNeedsToBeParticipant error to errors section in class
revert HostNeedsToBeParticipant();
}
if (participant[msg.sender]) {
participant[msg.sender] = false;
} else if (!participant[msg.sender] && block.timestamp <= deadline) {
participant[msg.sender] = true;
} else {
revert BeyondDeadline();
}
emit ChangedParticipation(msg.sender, participant[msg.sender]);
}
Updates

Lead Judging Commences

0xtimefliez Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Host can be non-participant

Appeal created

riceee Auditor
about 1 year ago
0xtimefliez Lead Judge
about 1 year ago
0xtimefliez Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Host can be non-participant

Support

FAQs

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

Give us feedback!