Beginner FriendlyGameFi
100 EXP
View results
Submission Details
Severity: medium
Valid

Manipulation Vulnerability in Time-Based Randomness Source and Airdrop Fund Security Risk

Root + Impact

Description

  • The normal behavior is that the module assigns a random pizza slice amount to each registered user for an airdrop, using the current timestamp's microseconds to generate the randomness. The amount is meant to be unpredictable and fairly distributed between 100 and 500 APT.

  • The specific issue is that the randomness source is solely based on the timestamp (timestamp::now_microseconds()), which is deterministic and manipulable. An attacker can manipulate transaction timing to predict or control the amount assigned, compromising fairness and security.

Risk

Likelihood:

  • Anytime a user or attacker can trigger the registration function during variable block/timestamp intervals, they can predict or influence the assigned amount.

  • In blockchains or environments where miners/validators can manipulate timestamps, the attacker can maximize their airdrop reward.

Impact:

  • Users with malicious intent can consistently receive higher allocations, leading to unfair distribution.

  • The airdrop fund may be disproportionately drained by attackers, damaging trust and causing financial loss.

Proof of Concept

fun get_random_slice(user_addr: address) acquires ModuleData, State {
let state = borrow_global_mut<State>(get_resource_address());
let time = timestamp::now_microseconds(); @> // Burada zaman bazlı rastgelelik kullanılıyor, sorun burası
let random_val = time % 401;
let random_amount = 100 + random_val;
table::add(&mut state.users_claimed_amount, user_addr, random_amount);
}

Recommended Mitigation

- -fun get_random_slice(user_addr: address) acquires ModuleData, State {
- let state = borrow_global_mut<State>(get_resource_address());
- let time = timestamp::now_microseconds();
- let random_val = time % 401;
- let random_amount = 100 + random_val;
- table::add(&mut state.users_claimed_amount, user_addr, random_amount);
-}
// Recommended: Use a secure randomness oracle or integrate with a blockchain-specific randomness beacon.
// Placeholder example (conceptual):
+fun get_random_slice(user_addr: address, random_seed: u64) acquires ModuleData, State {
+ let state = borrow_global_mut<State>(get_resource_address());
+ let random_val = random_seed % 401;
+ let random_amount = 100 + random_val;
+ table::add(&mut state.users_claimed_amount, user_addr, random_amount);
+}
Updates

Appeal created

bube Lead Judge 11 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Predictable randomness

The `get_random_slice` function should only be called by the owner via the `register_pizza_lover` function. Also, the `owner` is trusted and will not choose a specific time for a new user to register. Therefore, I disagree with the claim of most reports in this group that an attacker can manipulate the random number of pizza slices. But I agree with the root cause of the reports in this group, that the random distribution is not completely random.

Support

FAQs

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