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

Improper AccessControl in `RamNFT::mintRamNFT` allows anyone to mint RamNFT for free

Summary

The protocol expects users to mint RamNFT by calling Dussehra::enterPeopleWhoLikeRam and paying the entranceFee but anyone can mint RamNFT for free by calling the RamNFT::mintRamNFT function

Vulnerability Details

The function RamNFT::mintRamNFT can be called by anyone to mint RamNFT for free

Poc : Mint RamNFT for Free
function test_FreeNFTMint() public {
address ZeroBalanceUser = makeAddr("0 balance user");
vm.startPrank(ZeroBalanceUser);
ramNFT.mintRamNFT(ZeroBalanceUser);
vm.stopPrank();
//one NFT minted for free
assertEq(ramNFT.balanceOf(ZeroBalanceUser), 1);
// minting 2nd NFT
vm.startPrank(ZeroBalanceUser);
ramNFT.mintRamNFT(ZeroBalanceUser);
vm.stopPrank();
// also breaks the one NFT per address invariant
assertEq(ramNFT.balanceOf(ZeroBalanceUser), 2);
}

Impact

  1. Anyone Can Mint RamNFT for free without Paying the entranceFee

  2. Breaks the one RamNFT per address invariant i.e a user can mint two NFTs and become selectedRam by passing his tokenId's as args without worrying about randomness

  3. A Malicious user can become selectedRam for Free and steal rewards

Tools Used

  1. Manual Review

  2. Foundry

Recommendations

The RamNFT::mintRamNFT function should only be called by the Dussehra contract which will mitigate the issue

make the following changes in RamNFT.sol

  1. Declare a new Error error RamNFT__NotDussehraContract();

  2. Declare a new State Variable address public dussehraContract;

  3. Add a new Function

    function setDussehraContract(address _dussehraContract) public onlyOrganiser {
    dussehraContract = _dussehraContract;
    }
  4. Add a new Modifier

    modifier onlyDussehraContract() {
    if (msg.sender != dussehraContract) {
    revert RamNFT__NotDussehraContract();
    }
    _;
    }
  5. In the RamNFT::mintRamNFT function

- function mintRamNFT(address to) public {
+ function mintRamNFT(address to) public onlyDussehraContract {

Note: Add this line to Dussehra.t.sol's setup for tests to work

+ ramNFT.setDussehraContract(address(dussehra));
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.