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

Weak randomness

Root + Impact

Description

Normal behavior: register_pizza_lover assigns a “random” amount to each user, intended to be uniformly random in [100, 500].

Issue: The amount is derived from timestamp::now_microseconds(), which is predictable and manipulable (by validators and, in practice, schedulable by the privileged caller). This is not cryptographically random and can bias allocations.

// Root cause in the codebase with @> marks to highlight the relevant section
entry 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; // claims "random" 100–500
table::add(&mut state.users_claimed_amount, user_addr, random_amount);
}

Risk

Likelihood:

  • The “random” result is deterministically tied to the current timestamp; every call yields a predictable output.

  • A privileged registrant (owner) can repeatedly precompute/choose addresses or timings to favor high payouts.

Impact:

  • Unfair or biased distribution (e.g., consistently steering toward larger slices).

  • Loss of integrity/trust in the airdrop; potential reputational/complaint risk.

Recommended Mitigation

Use Aptos on-chain randomness API with #[randomness] and an entry function that calls it.

- let time = timestamp::now_microseconds();
- let random_val = time % 401;
- let random_amount = 100 + random_val; // 100–500 (not truly random)
+ use aptos_framework::randomness;
+ // Requires the entry function to be annotated with #[randomness]
+ let random_amount = 100 + randomness::u64_range(0, 401);

Notes: The #[randomness] attribute must be placed on the entry function that calls the randomness API or directly wraps it. See the Aptos docs

Updates

Appeal created

bube Lead Judge 10 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.