One Shot: Reloaded

First Flight #47
Beginner FriendlyNFT
100 EXP
View results
Submission Details
Impact: medium
Likelihood: low
Invalid

Self-Battles Possible, Leading to Wasted Gas or Manipulated Wins

Root + Impact

Description

  • Battles should only occur between different players.

  • The specific issue is no check preventing self-challenges, allowing self-battles that inflate wins without risk.

// In rap_battle.move
} else {
//@> // Missing: assert!(player_addr != arena.defender, E_SELF_BATTLE);
assert!(arena.defender_bet == bet_amount, E_BETS_DO_NOT_MATCH);
// ...
}

Risk

Likelihood: Low

  • User owns multiple NFTs.

  • User challenges their own defender position.

Impact: Medium

  • Artificial win inflation on NFTs.

  • Wasted gas on meaningless battles.

Proof of Concept

  • Go on stage with one NFT, challenge with another from same addr: battle proceeds, one NFT gains win.

#[test(module_owner = @battle_addr, player = @0x123)]
fun test_self_battle_possible(module_owner: &signer, player: &signer) acquires battle_addr::rap_battle::BattleArena, battle_addr::one_shot::Collection, battle_addr::one_shot::RapperStats {
// Setup: Initialize modules
battle_addr::cred_token::init_module(module_owner);
battle_addr::one_shot::init_module(module_owner);
battle_addr::rap_battle::init_module(module_owner);
// Mint two rappers to same player
battle_addr::one_shot::mint_rapper(module_owner, signer::address_of(player));
battle_addr::one_shot::mint_rapper(module_owner, signer::address_of(player));
// Go on stage with first
let rapper1 = /* assume */;
battle_addr::rap_battle::go_on_stage_or_battle(player, rapper1, 1);
// Challenge self with second
let rapper2 = /* assume */;
battle_addr::rap_battle::go_on_stage_or_battle(player, rapper2, 1);
// Battle proceeds: Check wins incremented on one
let token_id1 = /* assume */;
let (_, _, _, _, wins) = battle_addr::one_shot::read_stats(token_id1);
assert!(wins == 1 || /* check other */, 0); // Win manipulated
}

Recommended Mitigation

+ assert!(player_addr != arena.defender, E_SELF_BATTLE); // Add check
Updates

Lead Judging Commences

bube Lead Judge 16 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

The defender and challenger can be the same person

Even if the defender and challenger are not the same address. The player can use two different addresses and still be both defender and challenger at the same time. The intended behavior here is the same Rapper tokens to be not able to battle themself.

Support

FAQs

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