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

Randomness Predictability Vulnerability

Randomness Predictability Vulnerability

Description

The vulnerability stems from using timestamp::now_microseconds() as the source of randomness. This approach is fundamentally flawed because:

  1. Timestamps are predictable and can be anticipated by attackers.

  2. Miners/validators can influence or control block timestamps.

  3. The same timestamp will always produce the same "random" value.

#[randomness]
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; // 100-500 APT (in Octas: 10^8 smallest unit)
table::add(&mut state.users_claimed_amount, user_addr, random_amount);
}

Risk

Likelihood:
High

Impact:

  • Impact

  1. Users can potentially manipulate the system to receive maximum airdrop amounts (500 APT instead of random 100-500 APT)

  2. Fairness Impact: Undermines the fairness of the airdrop distribution mechanism

  3. Compromises the integrity of the entire airdrop system

Proof of Concept

An attacker could:

  1. Monitor blockchain timestamps

  2. Time their transaction submission to coincide with favorable timestamp values

  3. Potentially receive maximum airdrop amounts consistently

#[test]
fun test_secure_randomness() {
// With Aptos randomness, attacker cannot predict outcomes
let results = vector[];
for (i in 0..1000) {
let random_amount = get_secure_random_amount();
results.push_back(random_amount);
}
// Verify proper distribution (should be roughly uniform)
let distribution = analyze_distribution(results);
assert!(distribution.is_uniform, "Randomness should be properly distributed");
assert!(no_pattern_detected(results), "No predictable patterns should exist");
}

Recommended Mitigation

Use Aptos' built-in randomness API which provides cryptographically secure, unpredictable randomness:

+# use aptos_framework::random;
+
#[randomness]
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_val = random::random_u64() % 401; // Secure on-chain randomness
let random_amount = 100 + random_val; // 100-500 APT (in Octas: 10^8 smallest unit)
table::add(&mut state.users_claimed_amount, user_addr, random_amount);
}
Updates

Appeal created

bube Lead Judge about 1 month 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.