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

Anyone can mint multiple RamNFTs without paying the fixed fee and increase his chances to win due to improper access control on `RamNFT:mintRamNFT()`

Summary

Dussehra:enterPeopleWhoLikeRam() applies proper access control by reverting if an address tries to enter the competition multiple times.

if (peopleLikeRam[msg.sender] == true){
revert Dussehra__AlreadyPresent();
}

This is crucial because participants are pushed into the array peopleLikeRam whose length is later used to compute the total amount of collected fees:

uint256 totalAmountByThePeople = WantToBeLikeRam.length * entranceFee;

After validating the caller, enterPeopleWhoLikeRam() will proceed to mint a RamNFT for him by calling RamNFT:mintRamNFT().

However, RamNFT:mintRamNFT() is callable by anyone and allows to specify an arbitrary to address which will receive the NFT:

function mintRamNFT(address to) public {
uint256 newTokenId = tokenCounter++;
_safeMint(to, newTokenId);
Characteristics[newTokenId] = CharacteristicsOfRam({
ram: to,
isJitaKrodhah: false,
isDhyutimaan: false,
isVidvaan: false,
isAatmavan: false,
isSatyavaakyah: false
});
}

Impact

Users can participate without having to pay the entrance fee and with multiple NFTs, giving them more change to win and claim the 50% fee pot.

POC

Add the following test to test/Dussehra.t.sol:

function test_anyoneCanMintMultipleRamNFTs() public {
vm.deal(player1, 2 ether);
vm.startPrank(player1);
// obtain the first NFT legittimately
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
// if player1 tries enterPeopleWhoLikeRam() again the tx will revert
vm.expectRevert();
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
// mint more NFT without passing from dussehra contract
for (uint i; i < 10; i++) {
ramNFT.mintRamNFT(player1);
}
// player1 has 11 RamNFT and he only paid from 1!
assertEq(ramNFT.balanceOf(player1), 11);
vm.stopPrank();
}

Recommendations

Only allow the Dussehra contract to call RamNFT:mintRam(), for example the contract can be modified like this::

contract RamNft {
address public dussehra;
function setDussehraContract(address _d) external onlyOrganizer {
dussehra = _d;
}
function mintRamNFT(address to) public {
require(msg.sender == dussehra, "!Dussehra");
// rest of the code ...
}
}
Updates

Lead Judging Commences

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

mintRamNFT is public

Support

FAQs

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