Beginner FriendlyGameFi
100 EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Table Insert Errors

Root + Impact

Description

  • Normally, the table::add function in Move inserts a new key–value pair into a Table. It succeeds only if the key does not already exist.

  • In the PizzaDrop contract, the function that assigns pizza slices to registered users uses table::add. If a user has already been registered (or maliciously re-registered), the function will abort instead of updating their assigned slice. This breaks expected flow and can cause denial-of-service for that address.

public entry fun get_random_slice(account: address) {
let random_amount = 100 + (timestamp::now_microseconds() % 401);
@> table::add(&mut pizza_slices, account, random_amount);
// If account already exists, this aborts instead of updating/replacing
}

Risk

Likelihood:

  • This occurs whenever the same account is passed to get_random_slice after having already been inserted once.

  • Validators or misconfigured owner logic can unintentionally call it again on the same user, triggering aborts.

Impact:

  • Users can be permanently locked out from receiving a new slice if the owner tries to reassign them.

  • The contract state may abort mid-transaction, leading to denial-of-service or wasted gas for participants.

Proof of Concept

  • If the owner calls register_pizza_lover(deployer, user_addr) once, it succeeds. A second call for the same user_addr will hit table::add again, causing a VM abort (error code not defined in the module). The user will see a transaction revert without the module’s E_NOT_OWNER/E_ALREADY_CLAIMED codes.

// Example test: calling twice on the same address
airdrop::get_random_slice(@0x1);
// inserts successfully
airdrop::get_random_slice(@0x1);
// aborts with table::add "key already exists" error

Recommended Mitigation

  • Before adding a new key, check with table::contains, linke in the example below.

- table::add(&mut pizza_slices, account, random_amount);
+ if (table::contains(&pizza_slices, account)) {
+ table::remove(&mut pizza_slices, account);
+ }
+ table::insert(&mut pizza_slices, account, random_amount);
Updates

Appeal created

bube Lead Judge 9 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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