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

Users can claim multiple times

Root + Impact

The random slices per user is supposed to be fair, but this issue allows malicious parties to capitalize on the lack of checks that would prevent them from getting as many slices as they want. One user can potentially drain the entire pool of pizzas leaving nothing for the rest of the participants

Description

  • Normally, the contract is supposed to have a check so that users can claim only once

  • Since there is no check for who claimed, anyone can claim over and over without any limitations

public(entry) fun claim_pizza(user: &signer) {
// @> Missing check: has this address already claimed? <@
let slice = get_random_slice();
transfer_tokens_to(user, slice);
}

Risk

Likelihood:

  • Reason 1: There is nothing to prevent a user who already claimed slices from claiming again

  • Reason 2: This can happen over and over for as long as there are slices left in the pool

Impact:

  • Impact 1: One malicious user can completely drain the pool by calling the claim function repeatedly

  • Impact 2: The competition wouldn't be fair anymore

Proof of Concept

Since there is no check to see who already claimed, the claim function can be executed multiple times successfully by the same user

fun main(user: signer) {
// First claim
pizza_drop::claim_pizza(&user);
// Second claim — succeeds again
pizza_drop::claim_pizza(&user);
// Third claim — still works since there's no check to prevent it
pizza_drop::claim_pizza(&user);
}
  • Let's run a local node

aptos node run-local-testnet --with-faucet
  • Initialize an account

aptos init --profile user --network local
  • Deploy the contract

aptos move publish --profile user --named-addresses pizza_drop=user --skip-fetch-latest-git-deps //skipping dependencies updates because it's not working for me
  • Run the claim function more than once

aptos move run --profile user --function-id "0x6eef9ca6364aae9c99c06e9749a7c7170f4173834ad3ed8237bb7aa7b580472d::pizza_drop::get_random_slice"
aptos move run --profile user --function-id "0x6eef9ca6364aae9c99c06e9749a7c7170f4173834ad3ed8237bb7aa7b580472d::pizza_drop::get_random_slice" //should fail but it succeeds

The lack of check on who claimed and who didn't leads to multiple claims by the same user which violates the rules of the competition and makes it unfair for the rest of the participants

Recommended Mitigation

We add a check to make sure the user hasn't already claimed, if the user already did then the transaction fails. Also, everytime a succesful claim happens we store the user's address to keep track of who claimed and prevent multiple claims by the same user

- let slice = get_random_slice();
- transfer_tokens_to(user, slice);
+ assert!(!has_claimed(user_address_of(user)), AlreadyClaimed);
+ let slice = get_random_slice();
+ transfer_tokens_to(user, slice);
+ mark_as_claimed(user_address_of(user));
Updates

Appeal created

bube Lead Judge 12 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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