Description
The expected behavior is the rewarded amount is 100 - 500 APT Coins, but the amount coded for the drop is 100 to 500 in u64
, where that is 0.000001 - 0.000005 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;
table::add(&mut state.users_claimed_amount, user_addr, random_amount);
}
Risk
Likelihood:
Impact:
Proof of Concept
Running the test test_pizza_drop_with_apt
will result (assuming the randomness is 383):
[debug] "=== PIZZA DROP WITH APT TEST ==="
[debug] "Pizza drop module initialized"
[debug] "Deployer APT balance: "
[debug] 100000
[debug] "Contract APT balance: "
[debug] 10000
[debug] "User registered successfully"
[debug] "User assigned amount: "
[debug] 383
[debug] "User claimed their slice"
[debug] "User APT balance: "
[debug] 383
[debug] "Final contract balance: "
[debug] 9617
[debug] "Tracked balance: "
[debug] 9617
[debug] "=== PIZZA DROP TEST PASSED! ==="
Where user APT balance is 383 in u64
which means it is 0.00000383 APT.
Recommended Mitigation
Make the number represent 401 APT and 100 APT in random_val
and random_amount
variables by multiplying it to 100_000_000
#[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_val = time % 40100000000;
+ let random_amount = 10000000000 + random_val; // 100-500 APT (in Octas: 10^8 smallest unit)
table::add(&mut state.users_claimed_amount, user_addr, random_amount);
}