Closed rheaplex closed 2 years ago
I wanted to do an experiment the other day and try to see what happend when i listed the same item in rarible and at blocto bay. I was quite surprised when it turned out that i cannot. If i list something at rarible it is shown at blocto and I can then delist it at blocto.
Where a storefront contains more than one listing for the same NFT, all listings should be removed if:
This should be a public ability, as the token owner may not be the storefront owner.
It is also important to make sure that all listings can be removed, even if the successfully completed (purchased) one is removed. If a listing exists in a storefront that the token owner does not control, and the owner of that storefront removes its public capabilities, they will not be able to do so.
OPEN QUESTION: does this justify providing
access(contract)
functions on storefronts to prevent this? Discuss with Dete...Failure to remove all listings from all storefronts opens the token owner who created them to various attacks on the order of - https://finance.yahoo.com/news/cancel-old-opensea-listings-risk-163829354.html
I recommend two public functions in the
StorefrontPublic
interface. The first is an optimization. The second ensures that the first cannot be used to block removal of other listings by removing the completed listing.pub fun cleanupIfSameToken(purchasedResourceID: UInt64, otherResourceIDs: [UInt64])
This checks that the
purchasedResourceID
listing exists, and that it ispurchased
.If not, it fails the precondition.
If so, it gets the token
Type
andid
from it, then gets each listing in the otherResourceIDs list and removes it if it has the sameType
andid
. Finally, it removes the listing withpurchasedResourceID
.Note that we need not specify all listing resource IDs within the storefront instance in
otherResourceIDs
. We therefore need a less efficient function to ensure that any listings that refer to an absent token can be removed.pub fun cleanupIfTokenMoved(listingResourceID: UInt64)
This gets the listing and if its capability cannot be borrowed, removes it. If the capability resolves to something of the wrong type, it removes it. Finally, if the token of the specified
Type
andid
cannot be borrowed via the capability, it removes the listing.Note: an ideal solution to this would be link farms of Collection capabilities in each user's
private
storage, one per listing. I recommend revisiting this whenPath
wrangling supports it.