sherlock-audit / 2024-08-flayer-judging

0 stars 0 forks source link

Muscular Pebble Walrus - `listingCount` is not update in `relist()` #747

Open sherlock-admin4 opened 4 days ago

sherlock-admin4 commented 4 days ago

Muscular Pebble Walrus

Medium

listingCount is not update in relist()

Summary

listingCount is not update in relist()

Vulnerability Detail

relist() is used to relist any token. But the problem is, it assumes that only listed token will be relisted. However, floor tokens can also be relisted using relist(), which will not be included in listingCount.

 function relist(CreateListing calldata _listing, bool _payTaxWithEscrow) public nonReentrant lockerNotPaused {
        // Load our tokenId
        address _collection = _listing.collection;
        uint _tokenId = _listing.tokenIds[0];

        // Read the existing listing in a single read
        Listing memory oldListing = _listings[_collection][_tokenId];

        // Ensure the caller is not the owner of the listing
        if (oldListing.owner == msg.sender) revert CallerIsAlreadyOwner();

        // Load our new Listing into memory
        Listing memory listing = _listing.listing;

        // Ensure that the existing listing is available
        (bool isAvailable, uint listingPrice) = getListingPrice(_collection, _tokenId);
        if (!isAvailable) revert ListingNotAvailable();

        // We can process a tax refund for the existing listing
        (uint _fees,) = _resolveListingTax(oldListing, _collection, true);
        if (_fees != 0) {
            emit ListingFeeCaptured(_collection, _tokenId, _fees);
        }

        // Find the underlying {CollectionToken} attached to our collection
        ICollectionToken collectionToken = locker.collectionToken(_collection);

        // If the floor multiple of the original listings is different, then this needs
        // to be paid to the original owner of the listing.
        uint listingFloorPrice = 1 ether * 10 ** collectionToken.denomination();
        if (listingPrice > listingFloorPrice) {
            unchecked {
                collectionToken.transferFrom(msg.sender, oldListing.owner, listingPrice - listingFloorPrice);
            }
        }

        // Validate our new listing
        _validateCreateListing(_listing);

        // Store our listing into our Listing mappings
        _listings[_collection][_tokenId] = listing;

        // Pay our required taxes
        payTaxWithEscrow(address(collectionToken), getListingTaxRequired(listing, _collection), _payTaxWithEscrow);

        // Emit events
        emit ListingRelisted(_collection, _tokenId, listing);
    }

Now this will create problem while sunset/ closing of the collection because it checks the listingCount of the collection to ensure there is no listing. But due to above issue there will be listing & collection is sunset.

 function _hasListings(address _collection) internal view returns (bool) {
        IListings listings = locker.listings();
        if (address(listings) != address(0)) {
>           if (listings.listingCount(_collection) != 0) {
                return true;
            }

//
    }

Impact

Collection will be sunset even after having a listing

Code Snippet

https://github.com/sherlock-audit/2024-08-flayer/blob/main/flayer/src/contracts/utils/CollectionShutdown.sol#L497C4-L514C6 https://github.com/sherlock-audit/2024-08-flayer/blob/main/flayer/src/contracts/Listings.sol#L625

Tool used

Manual Review

Recommendation

Increase the listingCount if its floor token