Under normal conditions, users can mint Snow tokens by paying with ETH or WETH, and claim 1 free token every 7 days using earnSnow()
. However, the contract uses a global timer (s_earnTimer
) to enforce the cooldown, which is reset by anyone calling buySnow()
. This allows a malicious user to repeatedly buy small amounts of Snow and grief the system—effectively blocking all others from claiming their weekly rewards..
Likelihood:
This issue will occur whenever a user repeatedly calls the buySnow()
function, which is designed to reset the shared s_earnTimer
value.
Because there is no user-specific cooldown logic, any activity from a single user affects the entire protocol’s reward logic, making it trivial and cheap to abuse.
Impact:
All users can be indefinitely prevented from claiming their earnSnow()
reward.
This undermines user trust, breaks the intended reward mechanism, and introduces a denial-of-service vulnerability at the protocol level.
This proof-of-concept demonstrates how a malicious user can exploit the global s_earnTimer
by repeatedly calling buySnow()
just before the 7-day cooldown expires. Each call resets the global timer, effectively blocking all other users from ever meeting the earnSnow()
eligibility window.
The test simulates:
An attacker buying Snow (which resets the timer).
Advancing time close to the 7-day mark.
The attacker buying again just before others can earn.
A legitimate user attempting to call earnSnow()
and being reverted due to the reset.
This behavior confirms that the cooldown mechanism is vulnerable to griefing attacks, where a single malicious actor can deny rewards to the entire user base.
Proof of Concept (Forge Test)
The attacker repeatedly interacts with buySnow()
before the 7-day timer ends.
Since the timer is global, this denies all users from accessing the earnSnow()
function.
This makes the protocol griefable — where any user can block rewards for others indefinitely and at minimal cost.
Problem
The current implementation uses a shared global timer (s_earnTimer
) for throttling the earnSnow()
reward. This allows any user to grief the entire protocol by constantly resetting the timer.
Solution
Replace the global timer with a per-user timer mapping, so that each user independently tracks their cooldown period.
Code Fix
earnSnow()
function:Eliminates griefing by ensuring each user's cooldown is isolated.
Preserves original intent of one reward per user every 7 days.
Gas-efficient, scalable, and improves fairness of the reward mechanism.
When buySnow is successfully called, the global timer is reset. This inadvertently affects the earning of snow as that particular action also depends on the global timer.
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.