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

Weak randomness on `get_random_slice`

Description

The randomness on get_random_sliceis derived from timestamp::now_microseconds() which is not random. Malicious user can use this value to manipulate the amount that can be received on the drop and when the one that controls the owner is not truthful, the address that registered can be manipulated to get the highest amount possible (500 APT).

#[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:

  • Only the owner can execute the function, but there can be bias for the results. A malicious user may bias the result by picking the transaction submission time.

  • A malicious validator can bias the result easily by selecting which block the get_random_slice transaction goes to.

Impact:

  • Unfairness on the drop, as there is a possibility that every address is malicious.

  • Loss of funds.

Recommended Mitigation

Use randomness API provided by the aptos_framework.

+ #[randomness]
- public entry fun register_pizza_lover(owner: &signer, user: address) acquires ModuleData, State {
+ entry fun register_pizza_lover(owner: &signer, user: address) acquires ModuleData, State {
let state = borrow_global_mut<State>(get_resource_address());
assert!(signer::address_of(owner) == state.owner, E_NOT_OWNER);
get_random_slice(user);
event::emit(PizzaLoverRegistered {
user: user,
});
}
...
#[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)
+ let random_amount = aptos_framework::randomness::u64_range(100, 501); // 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 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.