Christmas Dinner

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

H-2: Improper State Update in refund Function

Summary

The refund function allows participants to reclaim their deposits (both ERC20 tokens and ETH) before the deadline. However, the function does not update the participant's state after the refund, leaving participant[msg.sender] as true. This can lead to significant vulnerabilities, as refunded participants might retain the ability to participate in functions intended only for active participants.

Vulnerability Details

Root Cause:
The refund function fails to reset the participant[msg.sender] state to false after a successful refund, allowing refunded users to retain participant privileges.

  • Expected Behavior:
    After a refund, participant[msg.sender] should be set to false, ensuring that the participant is no longer recognized as active and preventing unauthorized re-participation.

  • Current Behavior:
    The function refunds the participant’s balances but does not update the participant state. This allows refunded users to:

    1. Retain participant privileges.

    2. Access other functions restricted to participants.

Impact

This issue has critical consequences:

  1. State Inconsistency:
    The participant state does not align with the participant's actual status, leading to potential logical errors in the protocol.

  2. Economic Exploits:
    A malicious actor could repeatedly exploit this state inconsistency to gain unintended advantages.

Tools Used

  • Manual Code Review

  • Foundry

Recommendations

1. Update participant State in the refund Function
Modify the refund function to set participant[msg.sender] to false after successfully processing the refund:

function refund() external nonReentrant beforeDeadline {
address payable _to = payable(msg.sender);
_refundERC20(_to);
_refundETH(_to);
participant[msg.sender] = false;
emit Refunded(msg.sender);
}

2. Add Tests for Participant State Updates
Include unit tests to verify that the participant state is updated correctly after refunds.

Proof of Concept (PoC)

Exploit Scenario

  1. A user deposits funds and is marked as a participant (participant[msg.sender] = true).

  2. The user calls refund and retrieves their deposit.

  3. The participant[msg.sender] state remains true.

  4. The user could be the host or attend the event, for example.

function testRefundDoesNotUpdateState() public {
uint256 depositAmount = 1 ether;
vm.deal(user1, 10 ether);
vm.startPrank(user1);
ERC20Mock(weth).mint(user1, depositAmount);
ERC20Mock(weth).approve(address(cd), depositAmount);
cd.deposit(address(weth), depositAmount, user1);
cd.refund();
bool isParticipant = cd.getParticipationStatus(user1);
assertTrue(isParticipant, "User should no longer be a participant after refund");
vm.stopPrank();
}

By failing to update the participant's state, the refund function introduces the potential for state inconsistencies and economic exploits. Immediate remediation is required to ensure that refunded users are properly excluded from participant-only operations.

Updates

Lead Judging Commences

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

refund does not update participation status

Support

FAQs

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

Give us feedback!