Summary
The MartenitsaMarketplace::buyMartenitsa()
shoud return extra Money, if a user pay more than listing.price.
.
Vulnerability Details
In buyMartenitsa()
:
function buyMartenitsa(uint256 tokenId) external payable {
Listing memory listing = tokenIdToListing[tokenId];
require(listing.forSale, "Token is not listed for sale");
require(msg.value >= listing.price, "Insufficient funds");
address seller = listing.seller;
address buyer = msg.sender;
uint256 salePrice = listing.price;
martenitsaToken.updateCountMartenitsaTokensOwner(buyer, "add");
martenitsaToken.updateCountMartenitsaTokensOwner(seller, "sub");
delete tokenIdToListing[tokenId];
emit MartenitsaSold(tokenId, buyer, salePrice);
(bool sent,) = seller.call{value: salePrice}("");
require(sent, "Failed to send Ether");
martenitsaToken.safeTransferFrom(seller, buyer, tokenId);
}
There is no reFund, if a Martenitsa's price is 1 wei, but the buyer call the function with 1 ether, the extra money will not return to the buyer.
Impact
The buyer will loss his money.
Tools Used
Manual review, Foundry
Recommendations
function buyMartenitsa(uint256 tokenId) external payable {
Listing memory listing = tokenIdToListing[tokenId];
require(listing.forSale, "Token is not listed for sale");
require(msg.value >= listing.price, "Insufficient funds");
address seller = listing.seller;
address buyer = msg.sender;
uint256 salePrice = listing.price;
+ if (msg.value > salePrice) {
+ uint256 reFund = msg.value - salePrice;
+ (bool reFundsent,) = buyer.call{value: reFund}("");
+ require(reFundsent, "Failed to reFund Ether");
+ }
martenitsaToken.updateCountMartenitsaTokensOwner(buyer, "add");
martenitsaToken.updateCountMartenitsaTokensOwner(seller, "sub");
// Clear the listing
delete tokenIdToListing[tokenId];
emit MartenitsaSold(tokenId, buyer, salePrice);
// Transfer funds to seller
(bool sent,) = seller.call{value: salePrice}("");
require(sent, "Failed to send Ether");
// Transfer the token to the buyer
martenitsaToken.safeTransferFrom(seller, buyer, tokenId);
}