The receive()
function in the ChristmasDinner
smart contract allows users to send Ether to the contract. However, it does not properly update the participant status for users, leading to potential issues where users can deposit Ether multiple times without being considered participants. Unlike ERC20 deposits, where participation status is automatically updated, Ether depositors must manually invoke the changeParticipationStatus()
function to attend the event.
The receive()
function handles Ether deposits from users by updating the etherBalance
mapping, but it does not update the participant
status. The function simply adds the incoming Ether to the user's balance (etherBalance[msg.sender] += msg.value
) and emits a NewSignup
event. Unlike the deposit
function for ERC20 tokens, which correctly checks the user's participation status and updates it accordingly, this function does not enforce participation status, allowing users to deposit Ether multiple times without being marked as participants.
This oversight can lead to the following vulnerabilities:
Bypassing Participation Rules: Users can deposit multiple times without being considered participants, potentially leading to misuse or abuse of the contract’s features.
Inconsistency: The contract can become inconsistent in tracking who is actually participating in the event, which may lead to disputes or unexpected behaviors during the event.
Manual Action Requirement for Ether Depositors: Unlike ERC20 depositors who are automatically marked as participants, Ether depositors must manually invoke the changeParticipationStatus()
function to attend the event. This creates an unnecessary barrier and adds complexity to user interactions with the contract.
Data Inconsistency: Without proper status updates, the contract may not accurately reflect user participation.
Increased Risk of Abuse: Users can deposit Ether without triggering the participant flag, circumventing participation rules.
Potential Exploitation: Malicious actors could deposit Ether repeatedly, receiving event benefits without being registered as participants.
Manual Participation for Ether Depositors: Ether depositors must actively manage their participation status, unlike ERC20 depositors.
Manual Code Review: Reviewing contract logic and identifying discrepancies between functions handling different assets (Ether vs ERC20 tokens).
Static Analysis Tools: Used to validate function logic and identify non-conforming behavior.
Update the receive()
function to include participation status: Ensure that when Ether is received, the contract also
sets the user’s participation status to true
. This can be done by modifying the participant[msg.sender] = true;
line after updating the etherBalance
.
Code Consistency: Maintain consistency between the handling of different asset deposits (Ether and ERC20 tokens) to avoid discrepancies in tracking user status.
Additional Testing: Rigorously test the contract’s behavior with both ERC20 and Ether deposits to ensure all cases are covered, especially edge cases involving re-entrancy and multiple deposits.
Simplify Ether Depositor Participation: Consider simplifying the participation process for Ether depositors by automatically marking them as participants upon their deposit, similar to ERC20 depositors.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.