Beginner FriendlyFoundryGameFi
100 EXP
View results
Submission Details
Severity: medium
Invalid

Overwriting Issue in MartenitsaMarketplace::listMartenitsaForSale

Summary

The listMartenitsaForSale function in MartenitsaMarketplace allows producers to list the same martenitsa token multiple times, overwriting previous listings.

Vulnerability Details

Currently, the listMartenitsaForSale function does not prevent the re-listing of a martenitsa token already marked for sale, causing an overwrite of the previous listing data without checks.

function listMartenitsaForSale(uint256 tokenId, uint256 price) external {
require(
msg.sender == martenitsaToken.ownerOf(tokenId),
"You do not own this token"
);
require(
martenitsaToken.isProducer(msg.sender),
"You are not a producer!"
);
require(price > 0, "Price must be greater than zero");
Listing memory newListing = Listing({
tokenId: tokenId,
seller: msg.sender,
price: price,
design: martenitsaToken.getDesign(tokenId),
forSale: true
});
tokenIdToListing[tokenId] = newListing;
emit MartenitsaListed(tokenId, msg.sender, price);
}
POC

Add this test to MartenitsaMarketplace.test.sol:

function testListMartenitsaForSaleMultipleTimes() public createMartenitsa {
marketplace.listMartenitsaForSale(0, 1 wei);
marketplace.listMartenitsaForSale(0, 2 wei);
list = marketplace.getListing(0);
assert(list.price == 2 wei);
}

When the Producer lists the same martenitsa token multiple times for sale, the transaction is successful. This will overwrite the previous listing.

Test output:

run forge test --mt testListMartenitsaForSaleMultipleTimes and the result should PASS:

Ran 1 test for test/MartenitsaMarketplace.t.sol:MartenitsaMarketplace
[PASS] testListMartenitsaForSaleMultipleTimes() (gas: 341750)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 7.62ms (449.13µs CPU time)

Impact

The ability to list the same token multiple times without proper validation can lead to inconsistent listing states and potential misuse in token sales processes.

Tools Used

Foundry and Manual review.

Recommendations

To mitigate this issue, it is advisable to introduce a check that validates whether a token is already listed for sale:

function listMartenitsaForSale(uint256 tokenId, uint256 price) external {
+ require(tokenIdToListing[tokenId].forSale, "Token is already listed");
require(
msg.sender == martenitsaToken.ownerOf(tokenId),
"You do not own this token"
);
require(
martenitsaToken.isProducer(msg.sender),
"You are not a producer!"
);
require(price > 0, "Price must be greater than zero");
Listing memory newListing = Listing({
tokenId: tokenId,
seller: msg.sender,
price: price,
design: martenitsaToken.getDesign(tokenId),
forSale: true
});
tokenIdToListing[tokenId] = newListing;
emit MartenitsaListed(tokenId, msg.sender, price);
}

run forge test --mt testListMartenitsaForSaleMultipleTimes and the result should FAIL:

Failing tests:
Failing tests:
Encountered 1 failing test in test/MartenitsaMarketplace.t.sol:MartenitsaMarketplace
[FAIL. Reason: revert: Token is already listed] testListMartenitsaForSaleMultipleTimes() (gas: 137952)
Updates

Lead Judging Commences

bube Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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