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

Incorrect Unit Calculation of Distributed Random PizzaDrop Slices (APT)

Incorrect Unit Code Assumption Between APT and Octa Leads to Underpaying Users on Claim

Description

When a user signs up, they are allowed to claim PizzaDrop. Claiming PizzaDrop will provide them a random amount of APT between 100 to 500 as per the documentation.

Aptos transfers in units called octas. 1 APT = 100,000,000 octas (8 decimals). When transacting on Aptos outside of normal UIs, you must pass the amount in Octas.

In the pizza_drop::get_random_slice function, the calculation for the random_amount incorrectly assumes the number calculated will be expressed as APT, when its established above that APT is expressed as Octas on Aptos. If we focus on the following 3 lines here

#[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);
}

Proof of Concept

time is expressed as epoch format in microseconds. The calculation for the above will look like this based on the current epoch time:

time = 1756549650000
random_val = 1756549650000 % 401 = 133
random_amount = 100 + 133 = 233

This means the protocol is believed to provide the user with 233 APT when claiming their initial PizzaDrop.

However, as expressed previously, Aptos is expressed as Octas (100,000,000 | 10^8) so the user will only receive 0.00000233 APT, severely being underpaid on their claim.

As PizzaDrop is a core functional requirement of the Pizza Drop Protocol which all new users will utilise after signup, all users will be severely underpaid with "dust" amounts, therefore losing trust and favour in the protocol.

Risk

Likelihood: HIGH

  • Every user who signs up and claims PizzaDrop will be effected.

Impact: HIGH

  • Loss of trust with customers signing up

  • Heavy operational load to remediate customer issues

  • Immediately incident would be declared on release of Protocol to remediate core affected function

Recommended Mitigation

Declaration of APT/Octa should be added above the [event] declaration section for improved code-quality and to ensure we reduce any "Magic Numbers" in our code.

+ /// Units: 1 APT = 100,000,000 octas
+ const OCTA: u64 = 100_000_000;

And a modification to the get_random_slice function

#[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 = (100 + random_val) * OCTA // 100-500 APT (In Octas: 10^8 smallest unit)
table::add(&mut state.users_claimed_amount, user_addr, random_amount);
}

References

Updates

Appeal created

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

Incorrect APT value

Support

FAQs

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