sips
sips copied to clipboard
Trait for Marketplace functions
There should be a SIP that defines smart contract functions that enables an open, decentralized market place for digital assets. These assets must implement the operable
trait (#52).
Owners of operable assets should be able to list and unlist their token. Buyers should be able to buy the assets from the owner.
The marketplace
trait can be implemented as part of the asset contract (usually not recommended) or as an independent contract.
A simple trait would look like this:
(use-trait commission-trait .commisions.trait)
(define-trait marketplace
(
;; announce listing to global marketplace
;; must return `(ok true)` on success, never `(ok false)`
;; must send a list event
;; @param id; identifier of NFT or amount of FTs
;; @param price: of sale in micro STX
;; @param commission: action to happen after sale
(list-in-ustx (uint uint <commission-trait>) (response bool uint))
;; announce delisting to global marketplace
;; must return `(ok true)` on success, never `(ok false)`
;; must send a delist event
;; @param id; identifier of NFT or amount of FTs
(unlist-in-ustx (uint) (response bool uint))
;; buy and announce delisting to global marketplace
;; must return `(ok true)` on success, never `(ok false)`
;; commission must match the one set during listing
;; must send a delist event
;; @param id; identifier of NFT or amount of FTs
;; @param commission: action to happen after sale
(buy-in-ustx (uint <commission-trait>) (response bool uint))
;; read-only function defining the asset
(get-asset () (response {fq-contract: string, asset-class: string} uint))
)
)
(define-trait commission
(
;; additional action after a sale happened, usually a fee transfer for marketplaces
;; must return `(ok true)` on success, never `(ok false)`
;; @param id; identifier of NFT
;; @param price: of sale in micro STX
(pay (uint uint) (response bool uint))
)
)
Security
As commission-traits
can call any functions in the name of the tx-sender, it is important that a web app only offers commission contracts that are well understood. In particular, appropriate post-conditions have to be created.
If asset contracts want to control trades they have to restrict which operators are approved. Note, that royalties to an artist of an NFT can be part of the commission if agreed with the marketplace. They can also be implemented in the NFT directly.
Related Work
Loopbom https://github.com/radicleart/clarity-market
Megapont Ape Club https://explorer.stacks.co/txid/SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335.megapont-ape-club-nft?chain=mainnet
//cc @radicleart @MarvinJanssen @Jamil @dcsan @dantrevino
Reference material: https://github.com/ethereum/EIPs/issues/2907
Some thoughts here based on pain points dealing with the Megapont contract:
- exposing total % in the commission trait, as a read-only function
- having it as part of the standard to include commission in the listing price, not add it on top -- price for
list-in-ustx
and price paid forbuy-in-ustx
should be the same - separating artist royalty and marketplace commission traits, so the marketplaces don't need to deploy a different marketplace commission trait for every single NFT supported
additional thoughts:
- is it worth it to generalize this to SIP10 tokens as well? one of the things about including this functionality in the NFT contract is we want to be as future-proof as possible without adding too much bloat, so curious about your thoughts on this.
Agreed here that exposing the total % in the commission trait and including commission in this listing price, not on top would be great.
@friedger whole concept can be generalized and allow listing/un-listing/buying NFT's using STX and any SIP-010 compliant FT using one interface (see #60).
I would love to see the trait for a marketplace function standardized in a SIP. Do I understand correctly we are closing this in favor of #60: a more generalized interface so that any SIP-010 token can be used alongside STX to purchase said listed NFT?
I think current implementations on mainnet still have the commissions added on top of the listed price. Whereas @Jamil and @obsidianbtc were in favor of changing to listing with a price including the commissions, is that still the case? Would this need to be implemented in #60? Or would you prefer to keep the current way of working in the standard as you seem to have worked out a UI/UX to accommodate it already?
@314159265359879 This more generalized interface would be
(list-in-token (<transferable-trait> uint uint <commission-trait>) (response bool uint)) ...
The problem with the commission is that I don't see a standard way of calculating it. The commission contract can be an auction contract and the user initially listed it with a minimum price. Using the same price in list and buy function looks too rigid to me.
The commission contract can be also the single registry contract for all supported nfts because the contract-caller is the nft contract.