Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: medium
Valid

User can challenge self, making sure he/she always wins

Summary

The function ChoosingRam::increaseValuesOfParticipants allows users to compete against themselves by providing the same token ID for both the tokenIdOfChallenger and tokenIdOfAnyPerticipent parameters. This behavior guarantees that the user will always win since they are competing against themselves, which undermines the fairness and integrity of the competition.

Vulnerability Details

Function Affected: ChoosingRam::increaseValuesOfParticipants

Parameters: tokenIdOfChallenger, tokenIdOfAnyPerticipent

Issue: The function does not validate that tokenIdOfChallenger and tokenIdOfAnyPerticipent are different, allowing users to exploit this by passing the same token ID for both parameters.

Exploitation: A user can pass the same token ID for both tokenIdOfChallenger and tokenIdOfAnyPerticipent, ensuring that they always win the competition regardless of the outcome.

function increaseValuesOfParticipants(uint256 tokenIdOfChallenger, uint256 tokenIdOfAnyPerticipent)
public
RamIsNotSelected
{
if (tokenIdOfChallenger > ramNFT.tokenCounter()) {
revert ChoosingRam__InvalidTokenIdOfChallenger();
}
if (tokenIdOfAnyPerticipent > ramNFT.tokenCounter()) {
revert ChoosingRam__InvalidTokenIdOfPerticipent();
}
if (ramNFT.getCharacteristics(tokenIdOfChallenger).ram != msg.sender) {
revert ChoosingRam__CallerIsNotChallenger();
}
if (block.timestamp > 1728691200) {
revert ChoosingRam__TimeToBeLikeRamFinish();
}
uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, msg.sender))) % 2;
if (random == 0) {
if (ramNFT.getCharacteristics(tokenIdOfChallenger).isJitaKrodhah == false) {
ramNFT.updateCharacteristics(tokenIdOfChallenger, true, false, false, false, false);
} else if (ramNFT.getCharacteristics(tokenIdOfChallenger).isDhyutimaan == false) {
ramNFT.updateCharacteristics(tokenIdOfChallenger, true, true, false, false, false);
} else if (ramNFT.getCharacteristics(tokenIdOfChallenger).isVidvaan == false) {
ramNFT.updateCharacteristics(tokenIdOfChallenger, true, true, true, false, false);
} else if (ramNFT.getCharacteristics(tokenIdOfChallenger).isAatmavan == false) {
ramNFT.updateCharacteristics(tokenIdOfChallenger, true, true, true, true, false);
} else if (ramNFT.getCharacteristics(tokenIdOfChallenger).isSatyavaakyah == false) {
ramNFT.updateCharacteristics(tokenIdOfChallenger, true, true, true, true, true);
selectedRam = ramNFT.getCharacteristics(tokenIdOfChallenger).ram;
}
} else {
if (ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).isJitaKrodhah == false) {
ramNFT.updateCharacteristics(tokenIdOfAnyPerticipent, true, false, false, false, false);
} else if (ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).isDhyutimaan == false) {
ramNFT.updateCharacteristics(tokenIdOfAnyPerticipent, true, true, false, false, false);
} else if (ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).isVidvaan == false) {
ramNFT.updateCharacteristics(tokenIdOfAnyPerticipent, true, true, true, false, false);
} else if (ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).isAatmavan == false) {
ramNFT.updateCharacteristics(tokenIdOfAnyPerticipent, true, true, true, true, false);
} else if (ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).isSatyavaakyah == false) {
ramNFT.updateCharacteristics(tokenIdOfAnyPerticipent, true, true, true, true, true);
selectedRam = ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).ram;
}
}
}

Proof of Concept

  1. User pays entry fee to enters dussehra event

  2. User gets a minted nft

  3. User calls choosingRam.increaseValuesOfParticipants and passes his/her tokenId as tokenIdOfChallenger and tokenIdOfAnyPerticipent

  4. User wins the challenge

Proof of Code

modifier participants() {
vm.startPrank(player1);
vm.deal(player1, 1 ether);
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
vm.startPrank(player2);
vm.deal(player2, 1 ether);
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
_;
}
function test_increaseValuesOfParticipantsTest1() public participants {
vm.startPrank(player1);
choosingRam.increaseValuesOfParticipants(0, 0);
vm.stopPrank();
assertEq(ramNFT.getCharacteristics(0).isJitaKrodhah, true);
}

Impact

Fairness: This vulnerability allows users to manipulate the competition, leading to an unfair advantage. It compromises the integrity of the competitive aspect of the application.

Tools Used

Manual Review

Recommendations

To mitigate this vulnerability, implement a check within the increaseValuesOfParticipants function to ensure that tokenIdOfChallenger and tokenIdOfAnyPerticipent are not the same. This validation will prevent users from competing against themselves and ensure the integrity of the competition.

function increaseValuesOfParticipants(uint256 tokenIdOfChallenger, uint256 tokenIdOfAnyPerticipent) external {
require(tokenIdOfChallenger != tokenIdOfAnyPerticipent, "Challenger and participant cannot be the same token");
// Existing logic for increasing values
}
Updates

Lead Judging Commences

bube Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Challenge themselves

Support

FAQs

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